ScriptExecutor.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. #include "StdAfx.h"
  2. #include "ScriptExecutor.h"
  3. #include <fstream>
  4. #include <io.h>
  5. #include <fcntl.h>
  6. #include "Python.h"
  7. CScriptExecutor::CScriptExecutor(void)
  8. {
  9. m_hWorkThread = NULL;
  10. m_hWorkEvent = NULL;
  11. m_hLogThread = NULL;
  12. m_hLogEvent = NULL;
  13. m_bStatus = FALSE;
  14. m_nRunType = 0;
  15. m_hStdOutRead = NULL;
  16. m_hStdOutWrite = NULL;
  17. m_hStdErrorWrite = NULL;
  18. m_hOldStdOutWrite = NULL;
  19. memset(m_szScriptPath, 0, MAX_PATH);
  20. memset(m_szLogPath, 0, MAX_PATH);
  21. memset(m_szExtraSentence, 0, MAX_PATH);
  22. memset(&m_si, 0, sizeof(m_si));
  23. memset(&m_pi, 0, sizeof(m_pi));
  24. m_si.cb = sizeof(m_si);
  25. m_bKillProcess = FALSE;
  26. m_bStopLogExport = FALSE;
  27. m_dwThreadId = 0;
  28. m_dwSubprocessId = 0;
  29. m_bRuned = FALSE;
  30. }
  31. CScriptExecutor::~CScriptExecutor(void)
  32. {
  33. }
  34. DWORD CScriptExecutor::_WorkerThread(LPVOID lpParam)
  35. {
  36. CScriptExecutor* that = (CScriptExecutor*)lpParam;
  37. if ( !that )
  38. {
  39. printf("Error:参数失效\n");
  40. return -1;
  41. }
  42. if ( that->m_nRunType == EMBEDDED )
  43. {
  44. that->RedirectProcessStdout();
  45. ResumeThread(that->m_hLogThread);
  46. that->RunEmbeddedScript();
  47. }
  48. else if (that->m_nRunType == SUBPROCESS)
  49. {
  50. that->RunScripProcess();
  51. }
  52. CloseHandle(that->m_hWorkThread);
  53. that->m_hWorkThread = NULL;
  54. // 结束日志线程;
  55. that->m_bStopLogExport = TRUE;
  56. return 0;
  57. }
  58. DWORD CScriptExecutor::_LogExportThread(LPVOID lpParam)
  59. {
  60. CScriptExecutor* that = (CScriptExecutor*)lpParam;
  61. if (!that)
  62. {
  63. printf("Error:参数失效\n");
  64. return -1;
  65. }
  66. if (that->m_nRunType == SUBPROCESS)
  67. {
  68. DWORD dwRead;
  69. CHAR chBuf[BUFSIZE] = {0};
  70. BOOL bSuccess = FALSE;
  71. do
  72. {
  73. bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
  74. if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
  75. continue;
  76. Global::WritePythonLog(that->m_szLogPath, chBuf);
  77. memset(chBuf, 0, BUFSIZE);
  78. } while (!that->m_bStopLogExport);
  79. }
  80. else if ( that->m_nRunType == EMBEDDED)
  81. {
  82. DWORD dwRead;
  83. CHAR chBuf[BUFSIZE] = {0};
  84. BOOL bSuccess = FALSE;
  85. do
  86. {
  87. bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
  88. if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
  89. continue;
  90. Global::WritePythonLog(that->m_szLogPath, chBuf);
  91. memset(chBuf, 0, BUFSIZE);
  92. } while (!that->m_bStopLogExport);
  93. }
  94. // 关闭线程句柄;
  95. CloseHandle(that->m_hLogThread);
  96. that->m_hLogThread = NULL;
  97. // 结束重定向;
  98. that->EndSubprocessStdOut();
  99. return 0;
  100. }
  101. int CScriptExecutor::RedirectSubprocessStdout(LPSTARTUPINFO si /*=NULL*/)
  102. {
  103. #ifdef _DEBUG
  104. OutputDebugString("RedirectSubprocessStdout\n");
  105. #endif
  106. // Python脚本中,必须使用sys.__stdout__()
  107. if (m_nRunType == SUBPROCESS)
  108. {
  109. SECURITY_ATTRIBUTES sa;
  110. sa.bInheritHandle = TRUE;
  111. sa.lpSecurityDescriptor = NULL;
  112. sa.nLength = sizeof(sa);
  113. // 创建stdout的管道;
  114. if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, &sa, 0))
  115. {
  116. OutputDebugString("Error:创建stdout管道失败\n");
  117. return -1;
  118. }
  119. // 创建stderr的管道,由于stderr一般就是stdout,直接复制句柄;
  120. if (!DuplicateHandle(GetCurrentProcess(), m_hStdOutWrite, GetCurrentProcess(), &m_hStdErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
  121. {
  122. OutputDebugString("创建stderr管道失败\n");
  123. return -2;
  124. }
  125. si->dwFlags |= STARTF_USESTDHANDLES;
  126. // 将子进程的stdout输出到句柄hStdOutWrite;
  127. si->hStdOutput = m_hStdOutWrite;
  128. // 将子进程的stderr输出到句柄hStdErrWrite;
  129. si->hStdError = m_hStdErrorWrite;
  130. return 0;
  131. }
  132. // 异常类型;
  133. OutputDebugString("Error:异常类型\n");
  134. return -5;
  135. }
  136. int CScriptExecutor::RedirectProcessStdout()
  137. {
  138. #ifdef _DEBUG
  139. OutputDebugString("RedirectProcessStdout\n");
  140. #endif
  141. if (m_nRunType == EMBEDDED)
  142. {
  143. // 创建stdout的管道;
  144. if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0))
  145. {
  146. printf("Error:创建stdout管道失败\n");
  147. return -1;
  148. }
  149. // 将 C 运行时文件描述符与现有操作系统文件句柄关联;
  150. int wpfd = _open_osfhandle((intptr_t)m_hStdOutWrite, _O_TEXT);
  151. // 为stdout分配新文件描述符;
  152. if (_dup2(wpfd, _fileno(stdout)) != 0)
  153. {
  154. printf("Error:dup2调用失败");
  155. return -2;
  156. }
  157. _close(wpfd);
  158. // 备份进程原始标准输出;
  159. m_hOldStdOutWrite = GetStdHandle(STD_OUTPUT_HANDLE);
  160. // 设备进程标准输出,重定向到管道中;
  161. if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite))
  162. {
  163. printf("Error:重定向失败\n");
  164. return -3;
  165. }
  166. // 设置标准流不使用缓冲,即时写入;
  167. setvbuf(stdout, NULL, _IONBF, 0);
  168. return 0;
  169. }
  170. // 异常类型;
  171. printf("Error:异常类型\n");
  172. return -5;
  173. }
  174. void CScriptExecutor::CatchPythonException()
  175. {
  176. if (!Py_IsInitialized())
  177. {
  178. printf("Error:未初始化Python环境\n");
  179. return;
  180. }
  181. if (!PyErr_Occurred())
  182. {
  183. printf("Error:没有异常产生\n");
  184. return;
  185. }
  186. // 捕获异常;
  187. const char* pszErrMsg = NULL;
  188. TCHAR* pszTraceback = NULL;
  189. PyObject* pPyType = NULL;
  190. PyObject* pPyValue = NULL;
  191. PyObject* pPyTraceback = NULL;
  192. // 非控制台,使用PyErr_Fetch捕获异常;
  193. PyErr_Fetch(&pPyType, &pPyValue, &pPyTraceback);
  194. PyErr_NormalizeException(&pPyType, &pPyValue, &pPyTraceback); // 可有可无,不影响获取异常;
  195. if (pPyValue)
  196. {
  197. PyObject* pPyStr = PyObject_Str(pPyValue);
  198. if (PyString_Check(pPyStr))
  199. {
  200. pszErrMsg = PyString_AsString(pPyStr);
  201. if (pszErrMsg)
  202. printf("Error Info=>%s\n", pszErrMsg);
  203. if (pPyTraceback)
  204. {
  205. PyObject* pPyTraceModule = PyImport_ImportModule("traceback");
  206. if (!pPyTraceModule)
  207. {
  208. printf("Error:导入traceback模块失败\n");
  209. return;
  210. }
  211. #if 1 // 细分出所有换行符;
  212. PyObject* pPyModuleDict = PyModule_GetDict(pPyTraceModule);
  213. if (pPyModuleDict)
  214. {
  215. PyObject* pPyFunc = PyDict_GetItemString(pPyModuleDict, "format_exception");
  216. if (!pPyFunc || !PyCallable_Check(pPyFunc))
  217. {
  218. printf("Error:加载format_exception失败\n");
  219. return;
  220. }
  221. PyObject* pErroList = PyObject_CallFunctionObjArgs(pPyFunc, pPyType, pPyValue, pPyTraceback, NULL);
  222. if (pErroList)
  223. {
  224. int nSize = PyList_Size(pErroList);
  225. for (int i = 0; i < nSize; i++)
  226. {
  227. pszErrMsg = PyString_AsString(PyList_GetItem(pErroList, i));
  228. printf("%s", pszErrMsg);
  229. }
  230. }
  231. Py_DECREF(pErroList);
  232. }
  233. Py_XDECREF(pPyTraceModule);
  234. #else // 不细分Item;
  235. PyObject* pPyFunc = PyObject_GetAttrString(pPyTraceModule, "format_exception");
  236. if (!pPyFunc || !PyCallable_Check(pPyFunc))
  237. {
  238. printf("Error:加载format_exception失败\n");
  239. return;
  240. }
  241. PyObject* pPyResult = PyObject_CallFunctionObjArgs(pPyFunc, pPyType, pPyValue, pPyTraceback, NULL);
  242. pPyStr = PyObject_Str(pPyResult);
  243. pszErrMsg = PyString_AsString(pPyStr);
  244. if (pszErrMsg)
  245. printf("%s\n", pszErrMsg);
  246. Py_DECREF(pPyResult);
  247. Py_XDECREF(pPyTraceModule);
  248. #endif
  249. }
  250. }
  251. }
  252. Py_XDECREF(pPyType);
  253. Py_XDECREF(pPyValue);
  254. Py_XDECREF(pPyTraceback);
  255. }
  256. int CScriptExecutor::RunEmbeddedScript()
  257. {
  258. // 参数有效性判断;
  259. if (!PathFileExists(m_szScriptPath))
  260. {
  261. printf("Error:脚本文件不存在\n");
  262. return -1;
  263. }
  264. // 初始化Python环境;
  265. if (!Py_IsInitialized())
  266. Py_Initialize();
  267. if (!Py_IsInitialized())
  268. {
  269. printf("Error:初始化Python环境失败\n");
  270. return -2;
  271. }
  272. // 解析脚本路径和脚本名称;
  273. std::string scriptdir;
  274. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  275. TCHAR szDir[_MAX_DIR] = { 0 };
  276. TCHAR szExt[_MAX_EXT] = { 0 };
  277. TCHAR szFilename[_MAX_FNAME] = { 0 };
  278. TCHAR szScriptDir[MAX_PATH] = { 0 };
  279. _tsplitpath_s(m_szScriptPath, szDrive, szDir, szFilename, szExt);
  280. _stprintf_s(szScriptDir, _T("%s%s"), szDrive, szDir);
  281. // 缓存一份路径;
  282. scriptdir = szScriptDir;
  283. // 将'\'转换成'/', Python才设置运行目录成功;
  284. int len = _tcslen(szScriptDir);
  285. for (int i = 0; i < len; i++)
  286. {
  287. if (szScriptDir[i] == '\\')
  288. szScriptDir[i] = '/';
  289. }
  290. //szScriptDir[len-1] = '\0';
  291. TCHAR szExecuteDir[MAX_PATH] = { 0 };
  292. _stprintf_s(szExecuteDir, _T("sys.path.append(\"%s\")"), szScriptDir);
  293. // 添加系统模块,并指定当前脚本路径为运行路径;
  294. PyRun_SimpleString("import sys");
  295. PyRun_SimpleString(szExecuteDir);
  296. // 运行额外的语句,一般用于传递命令行参数;
  297. if (_tcslen(m_szExtraSentence))
  298. PyRun_SimpleString(m_szExtraSentence);
  299. // 注意:脚本名称尽量不要与系统目录其他py文件相同;
  300. // 导入脚本,以脚本名称为模块名加载;
  301. PyObject* pModuleObj = PyImport_ImportModule(szFilename);
  302. if (!pModuleObj)
  303. {
  304. printf("Error:加载脚本模块失败\n");
  305. Py_Finalize();
  306. return -3;
  307. }
  308. // 获取脚本的主函数名称(规定所有脚本的主函数名为main)
  309. // 加载函数:注意,如果目录下有同名的脚本文件,可能会加载失败;
  310. PyObject* pFunction = PyObject_GetAttrString(pModuleObj, "main");
  311. if (!pFunction || !PyCallable_Check(pFunction))
  312. {
  313. printf("Error:加载函数失败\n");
  314. Py_Finalize();
  315. return -4;
  316. }
  317. m_bRuned = TRUE;
  318. // 执行main函数;
  319. PyObject* pResult = PyObject_CallObject(pFunction, NULL);
  320. if (!pResult)
  321. {
  322. printf("Error:执行函数失败\n");
  323. CatchPythonException();
  324. Py_Finalize();
  325. return -5;
  326. }
  327. Py_DECREF(pResult);
  328. Py_Finalize();
  329. return 0;
  330. }
  331. int CScriptExecutor::RunScripProcess()
  332. {
  333. if (!PathFileExists(m_szScriptPath))
  334. {
  335. printf("Error:脚本路径无效\n");
  336. return -1;
  337. }
  338. // 初始化参数;
  339. ::memset(&m_si, 0, sizeof(m_si));
  340. ::memset(&m_pi, 0, sizeof(m_pi));
  341. m_si.cb = sizeof(m_si);
  342. GetStartupInfo(&m_si);
  343. // 强制stdion, stdout和stderr完全无缓冲:python -u
  344. TCHAR szCommandLine[MAX_PATH] = { 0 };
  345. if (_tcslen(m_szExtraSentence))
  346. _stprintf_s(szCommandLine, _T("python -W ignore -u %s %s"), m_szScriptPath, m_szExtraSentence);
  347. else
  348. _stprintf_s(szCommandLine, _T("python -W ignore -u %s"), m_szScriptPath);
  349. // 重定向输出;
  350. RedirectSubprocessStdout(&m_si);
  351. // 恢复日志线程;
  352. ResumeThread(m_hLogThread);
  353. // 启动子进程;
  354. if (!CreateProcess(
  355. NULL, // No module name (use command line)
  356. szCommandLine, // Command line
  357. NULL, // Process handle not inheritable
  358. NULL, // Thread handle not inheritable
  359. TRUE, // Set handle inheritance to TRUE
  360. 0, // No creation flags
  361. NULL, // Use parent's environment block
  362. NULL, // Use parent's starting directory
  363. &m_si, // Pointer to STARTUPINFO structure
  364. &m_pi) // Pointer to PROCESS_INFORMATION structure
  365. )
  366. {
  367. printf("Error:创建子进程失败 (%d).\n", GetLastError());
  368. return -3;
  369. }
  370. m_bRuned = TRUE;
  371. m_dwSubprocessId = m_pi.dwProcessId;
  372. // 等待进程完成退出.
  373. WaitForSingleObject(m_pi.hProcess, INFINITE);
  374. Sleep(5000);
  375. // 结束日志线程;
  376. m_bStopLogExport = TRUE;
  377. // 关闭进程句柄.
  378. CloseHandle(m_pi.hProcess);
  379. CloseHandle(m_pi.hThread);
  380. // 重置;
  381. memset(&m_si, 0, sizeof(m_si));
  382. memset(&m_pi, 0, sizeof(m_pi));
  383. m_si.cb = sizeof(m_si);
  384. return 0;
  385. }
  386. bool CScriptExecutor::StartWorkThread()
  387. {
  388. // 创建线程;
  389. m_hWorkThread = CreateThread(NULL, 0, _WorkerThread, this, 0, &m_dwThreadId);
  390. if (!m_hWorkThread)
  391. {
  392. printf("Error:创建线程失败\n");
  393. return false;
  394. }
  395. return true;
  396. }
  397. bool CScriptExecutor::StartLogThread()
  398. {
  399. printf("StartLogThread\n");
  400. // 创建线程事件:手动控制,无信号状态;
  401. m_hLogEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  402. if (!m_hLogEvent)
  403. {
  404. printf("Error:无法为线程创建控制事件\n");
  405. return false;
  406. }
  407. // 创建线程;
  408. m_hLogThread = CreateThread(NULL, 0, _LogExportThread, this, CREATE_SUSPENDED, NULL);
  409. if (!m_hLogThread)
  410. {
  411. printf("Error:创建线程失败\n");
  412. CloseHandle(m_hLogEvent);
  413. m_hLogEvent = NULL;
  414. return false;
  415. }
  416. return true;
  417. }
  418. void CScriptExecutor::EndWorkThread()
  419. {
  420. // 等待线程结束;
  421. if (m_hWorkThread)
  422. {
  423. // 尝试5次结束行为;
  424. for (int i = 0; i < 5; i++)
  425. {
  426. if (TerminateThread(m_hWorkThread, 0))
  427. break;
  428. }
  429. CloseHandle(m_hWorkThread);
  430. m_hWorkThread = NULL;
  431. }
  432. }
  433. void CScriptExecutor::EndLogThread()
  434. {
  435. // 设置事件有信号;
  436. if (m_hLogEvent)
  437. SetEvent(m_hLogEvent);
  438. // 等待线程结束;
  439. if (m_hLogThread)
  440. {
  441. WaitForSingleObject(m_hLogThread, INFINITE);
  442. CloseHandle(m_hLogThread);
  443. m_hLogThread = NULL;
  444. }
  445. // 关闭句柄;
  446. if (m_hLogEvent)
  447. CloseHandle(m_hLogEvent);
  448. m_hLogEvent = NULL;
  449. }
  450. void CScriptExecutor::EndThread(HANDLE hThread, HANDLE hEvent)
  451. {
  452. // 设置事件有信号;
  453. if (hEvent)
  454. SetEvent(hEvent);
  455. // 等待线程结束;
  456. if (hThread)
  457. {
  458. WaitForSingleObject(hThread, INFINITE);
  459. CloseHandle(hThread);
  460. hThread = NULL;
  461. }
  462. // 关闭句柄;
  463. if (hEvent)
  464. CloseHandle(hEvent);
  465. hEvent = NULL;
  466. }
  467. BOOL CScriptExecutor::EndSubprocess()
  468. {
  469. BOOL ret = false;
  470. if (m_pi.hProcess)
  471. {
  472. // 尝试5次结束;
  473. for (int i = 0; i < 5; i++)
  474. {
  475. if ( (ret = TerminateProcess(m_pi.hProcess, 0)) )
  476. break;
  477. }
  478. }
  479. return ret;
  480. }
  481. void CScriptExecutor::EndProcessStdOut()
  482. {
  483. OutputDebugString("--------------EndProcessStdOut----------------\n");
  484. #if 0 // 恢复失败,代码有问题
  485. // 恢复标准输出(嵌入进程脚本);
  486. if ( m_nRunType == EMBEDDED && m_hOldStdOutWrite)
  487. {
  488. int fn = _fileno(stdout);
  489. // 恢复进程默认标准输出;
  490. int fd = _open_osfhandle((intptr_t)m_hOldStdOutWrite, _O_RDWR);
  491. if ( _dup2(fd, _fileno(stdout)) == 0)
  492. {
  493. _close(fd);
  494. // 设置标准输出;
  495. SetStdHandle(STD_OUTPUT_HANDLE, m_hOldStdOutWrite);
  496. m_hOldStdOutWrite = NULL;
  497. // 设置标准流不使用缓冲,即时写入;
  498. setvbuf(stdout, NULL, _IONBF, 0);
  499. }
  500. else
  501. {
  502. printf("Error:_dup2分配文件描述符失败\n");
  503. }
  504. }
  505. #endif
  506. // 关闭重定向句柄;
  507. if (m_hStdErrorWrite)
  508. CloseHandle(m_hStdErrorWrite);
  509. m_hStdErrorWrite = NULL;
  510. // 只有子进程方式才关闭句柄;
  511. if ( m_hStdOutWrite)
  512. CloseHandle(m_hStdOutWrite);
  513. m_hStdOutWrite = NULL;
  514. if (m_hStdOutRead)
  515. CloseHandle(m_hStdOutRead);
  516. m_hStdOutRead = NULL;
  517. }
  518. void CScriptExecutor::EndSubprocessStdOut()
  519. {
  520. OutputDebugString("--------------EndSubprocessStdOut----------------\n");
  521. // 关闭重定向句柄;
  522. if (m_hStdErrorWrite)
  523. CloseHandle(m_hStdErrorWrite);
  524. m_hStdErrorWrite = NULL;
  525. // 只有子进程方式才关闭句柄;
  526. if ( m_hStdOutWrite)
  527. CloseHandle(m_hStdOutWrite);
  528. m_hStdOutWrite = NULL;
  529. if (m_hStdOutRead)
  530. CloseHandle(m_hStdOutRead);
  531. m_hStdOutRead = NULL;
  532. }
  533. void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
  534. {
  535. // 判断脚本是否存在;
  536. if (!PathFileExists(strScript.c_str()))
  537. {
  538. printf("Error:脚本文件不存在\n");
  539. return;
  540. }
  541. // 判断日志文件路径是否可创建;
  542. if (!PathFileExists(strLogPath.c_str()))
  543. {
  544. // 创建路径;
  545. if (!Global::MKDIR(strLogPath.c_str()))
  546. {
  547. printf("Error:创建目录失败\n");
  548. return;
  549. }
  550. // 创建文件;
  551. std::ofstream flog(strLogPath.c_str());
  552. if ( flog.bad() )
  553. {
  554. printf("Error:创建文件失败\n");
  555. return;
  556. }
  557. flog.close();
  558. }
  559. // 赋值参数;
  560. m_bRuned = FALSE;
  561. m_nRunType = nRunType;
  562. m_dwThreadId = m_dwSubprocessId = 0;
  563. _tcscpy_s(m_szScriptPath, strScript.c_str());
  564. _tcscpy_s(m_szLogPath, strLogPath.c_str());
  565. _tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
  566. }
  567. bool CScriptExecutor::StartScript()
  568. {
  569. if (StartWorkThread())
  570. {
  571. // 开启日志导出线程;
  572. if (!StartLogThread())
  573. {
  574. printf("Error:日志导出线程创建出错\n");
  575. }
  576. Sleep(100);
  577. return true;
  578. }
  579. // 异常类型;
  580. printf("Error:异常类型脚本\n");
  581. return false;
  582. }
  583. void CScriptExecutor::StopScript()
  584. {
  585. // 如果是子进程运行脚本,停止线程时kill进程;
  586. if (m_nRunType == SUBPROCESS)
  587. EndSubprocess();
  588. // 结束线程;
  589. EndWorkThread();
  590. }
  591. bool CScriptExecutor::IsScriptOver()
  592. {
  593. int i = 10;
  594. while (!m_bRuned)
  595. {
  596. Sleep(300);
  597. if ( --i == 0 )
  598. break;
  599. }
  600. if (m_nRunType == EMBEDDED)
  601. {
  602. if ( m_hWorkThread == NULL )
  603. return true;
  604. }
  605. else if (m_nRunType == SUBPROCESS)
  606. {
  607. if ( m_pi.hProcess == NULL && m_hWorkThread == NULL )
  608. return true;
  609. }
  610. return false;
  611. }