ScriptExecutor.cpp 15 KB

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