123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- #include "StdAfx.h"
- #include "ScriptExecutor.h"
- #include <fstream>
- #include <io.h>
- #include <fcntl.h>
- CScriptExecutor::CScriptExecutor(void)
- {
- m_hWorkThread = NULL;
- m_hWorkEvent = NULL;
- m_hLogThread = NULL;
- m_hLogEvent = NULL;
- m_bStatus = FALSE;
- m_nRunType = 0;
- m_hStdOutRead = NULL;
- m_hStdOutWrite = NULL;
- m_hStdErrorWrite = NULL;
- m_hOldStdOutWrite = NULL;
- memset(m_szScriptPath, 0, MAX_PATH);
- memset(m_szLogPath, 0, MAX_PATH);
- memset(m_szExtraSentence, 0, MAX_PATH);
- memset(&m_si, 0, sizeof(m_si));
- memset(&m_pi, 0, sizeof(m_pi));
- m_si.cb = sizeof(m_si);
- m_bKillProcess = FALSE;
- m_bStopLogExport = FALSE;
- m_dwThreadId = 0;
- m_dwSubprocessId = 0;
- m_bRuned = FALSE;
- }
- CScriptExecutor::~CScriptExecutor(void)
- {
- }
- DWORD CScriptExecutor::_WorkerThread(LPVOID lpParam)
- {
- CScriptExecutor* that = (CScriptExecutor*)lpParam;
- if ( !that )
- {
- printf("Error:参数失效\n");
- return -1;
- }
- if ( that->m_nRunType == EMBEDDED )
- {
- that->RedirectProcessStdout();
- ResumeThread(that->m_hLogThread);
- that->RunEmbeddedScript();
- }
- else if (that->m_nRunType == SUBPROCESS)
- {
- that->RunScripProcess();
- }
- CloseHandle(that->m_hWorkThread);
- that->m_hWorkThread = NULL;
-
- that->m_bStopLogExport = TRUE;
- return 0;
- }
- DWORD CScriptExecutor::_LogExportThread(LPVOID lpParam)
- {
- CScriptExecutor* that = (CScriptExecutor*)lpParam;
- if (!that)
- {
- printf("Error:参数失效\n");
- return -1;
- }
- if (that->m_nRunType == SUBPROCESS)
- {
- DWORD dwRead;
- CHAR chBuf[BUFSIZE] = {0};
- BOOL bSuccess = FALSE;
-
- do
- {
- bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
- if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
- continue;
- Global::WritePythonLog(that->m_szLogPath, chBuf);
- memset(chBuf, 0, BUFSIZE);
- } while (!that->m_bStopLogExport);
- }
- else if ( that->m_nRunType == EMBEDDED)
- {
- DWORD dwRead;
- CHAR chBuf[BUFSIZE] = {0};
- BOOL bSuccess = FALSE;
- do
- {
- bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
- if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
- continue;
- Global::WritePythonLog(that->m_szLogPath, chBuf);
- memset(chBuf, 0, BUFSIZE);
- } while (!that->m_bStopLogExport);
- }
-
- CloseHandle(that->m_hLogThread);
- that->m_hLogThread = NULL;
-
- that->EndSubprocessStdOut();
- return 0;
- }
- int CScriptExecutor::RedirectSubprocessStdout(LPSTARTUPINFO si )
- {
- #ifdef _DEBUG
- OutputDebugString("RedirectSubprocessStdout\n");
- #endif
-
- if (m_nRunType == SUBPROCESS)
- {
- SECURITY_ATTRIBUTES sa;
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
- sa.nLength = sizeof(sa);
-
- if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, &sa, 0))
- {
- OutputDebugString("Error:创建stdout管道失败\n");
- return -1;
- }
-
- if (!DuplicateHandle(GetCurrentProcess(), m_hStdOutWrite, GetCurrentProcess(), &m_hStdErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
- {
- OutputDebugString("创建stderr管道失败\n");
- return -2;
- }
- si->dwFlags |= STARTF_USESTDHANDLES;
-
- si->hStdOutput = m_hStdOutWrite;
-
- si->hStdError = m_hStdErrorWrite;
- return 0;
- }
-
- OutputDebugString("Error:异常类型\n");
- return -5;
- }
- int CScriptExecutor::RedirectProcessStdout()
- {
- #ifdef _DEBUG
- OutputDebugString("RedirectProcessStdout\n");
- #endif
- if (m_nRunType == EMBEDDED)
- {
-
- if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0))
- {
- printf("Error:创建stdout管道失败\n");
- return -1;
- }
-
- int wpfd = _open_osfhandle((intptr_t)m_hStdOutWrite, _O_TEXT);
-
- if (_dup2(wpfd, _fileno(stdout)) != 0)
- {
- printf("Error:dup2调用失败");
- return -2;
- }
- _close(wpfd);
-
- m_hOldStdOutWrite = GetStdHandle(STD_OUTPUT_HANDLE);
-
- if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite))
- {
- printf("Error:重定向失败\n");
- return -3;
- }
-
- setvbuf(stdout, NULL, _IONBF, 0);
- return 0;
- }
-
- printf("Error:异常类型\n");
- return -5;
- }
- void CScriptExecutor::CatchPythonException()
- {
- if (!Py_IsInitialized())
- {
- printf("Error:未初始化Python环境\n");
- return;
- }
- if (!PyErr_Occurred())
- {
- printf("Error:没有异常产生\n");
- return;
- }
-
- const char* pszErrMsg = NULL;
- TCHAR* pszTraceback = NULL;
- PyObject* pPyType = NULL;
- PyObject* pPyValue = NULL;
- PyObject* pPyTraceback = NULL;
-
- PyErr_Fetch(&pPyType, &pPyValue, &pPyTraceback);
- PyErr_NormalizeException(&pPyType, &pPyValue, &pPyTraceback);
- if (pPyValue)
- {
- PyObject* pPyStr = PyObject_Str(pPyValue);
- if (PyString_Check(pPyStr))
- {
- pszErrMsg = PyString_AsString(pPyStr);
- if (pszErrMsg)
- printf("Error Info=>%s\n", pszErrMsg);
- if (pPyTraceback)
- {
- PyObject* pPyTraceModule = PyImport_ImportModule("traceback");
- if (!pPyTraceModule)
- {
- printf("Error:导入traceback模块失败\n");
- return;
- }
- #if 1
- PyObject* pPyModuleDict = PyModule_GetDict(pPyTraceModule);
- if (pPyModuleDict)
- {
- PyObject* pPyFunc = PyDict_GetItemString(pPyModuleDict, "format_exception");
- if (!pPyFunc || !PyCallable_Check(pPyFunc))
- {
- printf("Error:加载format_exception失败\n");
- return;
- }
- PyObject* pErroList = PyObject_CallFunctionObjArgs(pPyFunc, pPyType, pPyValue, pPyTraceback, NULL);
- if (pErroList)
- {
- int nSize = PyList_Size(pErroList);
- for (int i = 0; i < nSize; i++)
- {
- pszErrMsg = PyString_AsString(PyList_GetItem(pErroList, i));
- printf("%s", pszErrMsg);
- }
- }
- Py_DECREF(pErroList);
- }
- Py_XDECREF(pPyTraceModule);
- #else
- PyObject* pPyFunc = PyObject_GetAttrString(pPyTraceModule, "format_exception");
- if (!pPyFunc || !PyCallable_Check(pPyFunc))
- {
- printf("Error:加载format_exception失败\n");
- return;
- }
- PyObject* pPyResult = PyObject_CallFunctionObjArgs(pPyFunc, pPyType, pPyValue, pPyTraceback, NULL);
- pPyStr = PyObject_Str(pPyResult);
- pszErrMsg = PyString_AsString(pPyStr);
- if (pszErrMsg)
- printf("%s\n", pszErrMsg);
- Py_DECREF(pPyResult);
- Py_XDECREF(pPyTraceModule);
- #endif
- }
- }
- }
- Py_XDECREF(pPyType);
- Py_XDECREF(pPyValue);
- Py_XDECREF(pPyTraceback);
- }
- int CScriptExecutor::RunEmbeddedScript()
- {
-
- if (!PathFileExists(m_szScriptPath))
- {
- printf("Error:脚本文件不存在\n");
- return -1;
- }
-
- if (!Py_IsInitialized())
- Py_Initialize();
- if (!Py_IsInitialized())
- {
- printf("Error:初始化Python环境失败\n");
- return -2;
- }
-
- std::string scriptdir;
- TCHAR szDrive[_MAX_DRIVE] = { 0 };
- TCHAR szDir[_MAX_DIR] = { 0 };
- TCHAR szExt[_MAX_EXT] = { 0 };
- TCHAR szFilename[_MAX_FNAME] = { 0 };
- TCHAR szScriptDir[MAX_PATH] = { 0 };
- _tsplitpath_s(m_szScriptPath, szDrive, szDir, szFilename, szExt);
- _stprintf_s(szScriptDir, _T("%s%s"), szDrive, szDir);
-
- scriptdir = szScriptDir;
-
- int len = _tcslen(szScriptDir);
- for (int i = 0; i < len; i++)
- {
- if (szScriptDir[i] == '\\')
- szScriptDir[i] = '/';
- }
-
- TCHAR szExecuteDir[MAX_PATH] = { 0 };
- _stprintf_s(szExecuteDir, _T("sys.path.append(\"%s\")"), szScriptDir);
-
- PyRun_SimpleString("import sys");
- PyRun_SimpleString(szExecuteDir);
-
- if (_tcslen(m_szExtraSentence))
- PyRun_SimpleString(m_szExtraSentence);
-
-
- PyObject* pModuleObj = PyImport_ImportModule(szFilename);
- if (!pModuleObj)
- {
- printf("Error:加载脚本模块失败\n");
- Py_Finalize();
- return -3;
- }
-
-
- PyObject* pFunction = PyObject_GetAttrString(pModuleObj, "main");
- if (!pFunction || !PyCallable_Check(pFunction))
- {
- printf("Error:加载函数失败\n");
- Py_Finalize();
- return -4;
- }
- m_bRuned = TRUE;
-
- PyObject* pResult = PyObject_CallObject(pFunction, NULL);
- if (!pResult)
- {
- printf("Error:执行函数失败\n");
- CatchPythonException();
- Py_Finalize();
-
- return -5;
- }
- Py_DECREF(pResult);
- Py_Finalize();
- return 0;
- }
- int CScriptExecutor::RunScripProcess()
- {
- if (!PathFileExists(m_szScriptPath))
- {
- printf("Error:脚本路径无效\n");
- return -1;
- }
-
- ::memset(&m_si, 0, sizeof(m_si));
- ::memset(&m_pi, 0, sizeof(m_pi));
- m_si.cb = sizeof(m_si);
- GetStartupInfo(&m_si);
-
- TCHAR szCommandLine[MAX_PATH] = { 0 };
- if (_tcslen(m_szExtraSentence))
- _stprintf_s(szCommandLine, _T("python -W ignore -u %s %s"), m_szScriptPath, m_szExtraSentence);
- else
- _stprintf_s(szCommandLine, _T("python -W ignore -u %s"), m_szScriptPath);
-
- RedirectSubprocessStdout(&m_si);
-
- ResumeThread(m_hLogThread);
-
- if (!CreateProcess(
- NULL,
- szCommandLine,
- NULL,
- NULL,
- TRUE,
- 0,
- NULL,
- NULL,
- &m_si,
- &m_pi)
- )
- {
- printf("Error:创建子进程失败 (%d).\n", GetLastError());
- return -3;
- }
- m_bRuned = TRUE;
- m_dwSubprocessId = m_pi.dwProcessId;
-
- WaitForSingleObject(m_pi.hProcess, INFINITE);
- Sleep(5000);
-
- m_bStopLogExport = TRUE;
-
- CloseHandle(m_pi.hProcess);
- CloseHandle(m_pi.hThread);
-
- memset(&m_si, 0, sizeof(m_si));
- memset(&m_pi, 0, sizeof(m_pi));
- m_si.cb = sizeof(m_si);
- return 0;
- }
- bool CScriptExecutor::StartWorkThread()
- {
-
- m_hWorkThread = CreateThread(NULL, 0, _WorkerThread, this, 0, &m_dwThreadId);
- if (!m_hWorkThread)
- {
- printf("Error:创建线程失败\n");
- return false;
- }
- return true;
- }
- bool CScriptExecutor::StartLogThread()
- {
- printf("StartLogThread\n");
-
- m_hLogEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!m_hLogEvent)
- {
- printf("Error:无法为线程创建控制事件\n");
- return false;
- }
-
- m_hLogThread = CreateThread(NULL, 0, _LogExportThread, this, CREATE_SUSPENDED, NULL);
- if (!m_hLogThread)
- {
- printf("Error:创建线程失败\n");
- CloseHandle(m_hLogEvent);
- m_hLogEvent = NULL;
- return false;
- }
- return true;
- }
- void CScriptExecutor::EndWorkThread()
- {
-
- if (m_hWorkThread)
- {
-
- for (int i = 0; i < 5; i++)
- {
- if (TerminateThread(m_hWorkThread, 0))
- break;
- }
- CloseHandle(m_hWorkThread);
- m_hWorkThread = NULL;
- }
- }
- void CScriptExecutor::EndLogThread()
- {
-
- if (m_hLogEvent)
- SetEvent(m_hLogEvent);
-
- if (m_hLogThread)
- {
- WaitForSingleObject(m_hLogThread, INFINITE);
- CloseHandle(m_hLogThread);
- m_hLogThread = NULL;
- }
-
- if (m_hLogEvent)
- CloseHandle(m_hLogEvent);
- m_hLogEvent = NULL;
- }
- void CScriptExecutor::EndThread(HANDLE hThread, HANDLE hEvent)
- {
-
- if (hEvent)
- SetEvent(hEvent);
-
- if (hThread)
- {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- hThread = NULL;
- }
-
- if (hEvent)
- CloseHandle(hEvent);
- hEvent = NULL;
- }
- BOOL CScriptExecutor::EndSubprocess()
- {
- BOOL ret = false;
- if (m_pi.hProcess)
- {
-
- for (int i = 0; i < 5; i++)
- {
- if ( (ret = TerminateProcess(m_pi.hProcess, 0)) )
- break;
- }
- }
- return ret;
- }
- void CScriptExecutor::EndProcessStdOut()
- {
- OutputDebugString("--------------EndProcessStdOut----------------\n");
- #if 0
-
- if ( m_nRunType == EMBEDDED && m_hOldStdOutWrite)
- {
- int fn = _fileno(stdout);
-
- int fd = _open_osfhandle((intptr_t)m_hOldStdOutWrite, _O_RDWR);
- if ( _dup2(fd, _fileno(stdout)) == 0)
- {
- _close(fd);
-
- SetStdHandle(STD_OUTPUT_HANDLE, m_hOldStdOutWrite);
- m_hOldStdOutWrite = NULL;
-
- setvbuf(stdout, NULL, _IONBF, 0);
- }
- else
- {
- printf("Error:_dup2分配文件描述符失败\n");
- }
- }
- #endif
-
- if (m_hStdErrorWrite)
- CloseHandle(m_hStdErrorWrite);
- m_hStdErrorWrite = NULL;
-
- if ( m_hStdOutWrite)
- CloseHandle(m_hStdOutWrite);
- m_hStdOutWrite = NULL;
- if (m_hStdOutRead)
- CloseHandle(m_hStdOutRead);
- m_hStdOutRead = NULL;
- }
- void CScriptExecutor::EndSubprocessStdOut()
- {
- OutputDebugString("--------------EndSubprocessStdOut----------------\n");
-
- if (m_hStdErrorWrite)
- CloseHandle(m_hStdErrorWrite);
- m_hStdErrorWrite = NULL;
-
- if ( m_hStdOutWrite)
- CloseHandle(m_hStdOutWrite);
- m_hStdOutWrite = NULL;
- if (m_hStdOutRead)
- CloseHandle(m_hStdOutRead);
- m_hStdOutRead = NULL;
- }
- void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType )
- {
-
- if (!PathFileExists(strScript.c_str()))
- {
- printf("Error:脚本文件不存在\n");
- return;
- }
-
- if (!PathFileExists(strLogPath.c_str()))
- {
-
- if (!Global::MKDIR(strLogPath.c_str()))
- {
- printf("Error:创建目录失败\n");
- return;
- }
-
- std::ofstream flog(strLogPath.c_str());
- if ( flog.bad() )
- {
- printf("Error:创建文件失败\n");
- return;
- }
- flog.close();
- }
-
- m_bRuned = FALSE;
- m_nRunType = nRunType;
- m_dwThreadId = m_dwSubprocessId = 0;
- _tcscpy_s(m_szScriptPath, strScript.c_str());
- _tcscpy_s(m_szLogPath, strLogPath.c_str());
- _tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
- }
- bool CScriptExecutor::StartScript()
- {
- if (StartWorkThread())
- {
-
- if (!StartLogThread())
- {
- printf("Error:日志导出线程创建出错\n");
- }
- Sleep(100);
- return true;
- }
-
- printf("Error:异常类型脚本\n");
- return false;
- }
- void CScriptExecutor::StopScript()
- {
-
- if (m_nRunType == SUBPROCESS)
- EndSubprocess();
-
- EndWorkThread();
- }
- bool CScriptExecutor::IsScriptOver()
- {
- int i = 10;
- while (!m_bRuned)
- {
- Sleep(300);
- if ( --i == 0 )
- break;
- }
- if (m_nRunType == EMBEDDED)
- {
- if ( m_hWorkThread == NULL )
- return true;
- }
- else if (m_nRunType == SUBPROCESS)
- {
- if ( m_pi.hProcess == NULL && m_hWorkThread == NULL )
- return true;
- }
- return false;
- }
|