#ifndef __SCRIPT_EXECUTOR__ #define __SCRIPT_EXECUTOR__ #pragma once #define BUFSIZE 4096 enum PY_RUN_TYPE { EMBEDDED, // 嵌入到本进程运行; SUBPROCESS // 以子进程方式运行; }; class CScriptExecutor { public: CScriptExecutor(void); ~CScriptExecutor(void); protected: SATHTTP::STCase *m_pCaseObj; // 用例对象; HANDLE m_hWorkThread; // 事件句柄; HANDLE m_hStdoutLogThread; // 事件句柄; BOOL m_bStatus; // 线程状态; TCHAR m_szScriptPath[MAX_PATH]; // 脚本路径; TCHAR m_szLogPath[MAX_PATH]; // 日志路径; TCHAR m_szExtraSentence[MAX_PATH]; // 脚本命令行参数或额外要执行的语句; int m_nRunType; // 重定向标准输出和标准错误; HANDLE m_hStdOutRead; HANDLE m_hStdOutWrite; HANDLE m_hStdErrorRead; HANDLE m_hStdErrorWrite; HANDLE m_hOldStdOutWrite; // 用于本进程标准输出备份; // 子进程信息; STARTUPINFO m_si; PROCESS_INFORMATION m_pi; // 进程结束标志; BOOL m_bKillProcess; // 停止日志导出线程; BOOL m_bStopLogExport; // 执行器执行时间; CTime m_tStartTime; ULONGLONG m_ulStartTickCount; // 执行器结束时间; CTime m_tEndTime; // 子进程ID; DWORD m_dwSubprocessId; // 线程ID; DWORD m_dwThreadId; // 脚本是否成功运行; BOOL m_bRuned; protected: // 工作者线程函数; static DWORD WINAPI _WorkerThread(LPVOID lpParam); // 日志导出线程; static DWORD WINAPI _StdoutLogExportThread(LPVOID lpParam); static DWORD WINAPI _StderrLogExportThread(LPVOID lpParam); // 重定向本进程标准输出; int RedirectProcessStdout(); // 重定子进程向标准输出; int RedirectSubprocessStdout(LPSTARTUPINFO si = NULL); // 获取Python异常; void CatchPythonException(); // 运行嵌入的脚本; int RunEmbeddedScript(); // 运行脚本进程; int RunScriptProcess(); // 在服务进程中创建脚本进程; int ServiceRunScriptProcess(); // 开启线程; bool StartThread(); // 结束线程; void EndWorkThread(); void EndLogThread(); void EndThread(); // 从管道读取日志; void ReadFromPipe(); // 结束重定向句柄,恢复默认; void EndProcessStdOut(); void EndSubprocessStdOut(); // 获取当前活动的会话ID; DWORD GetActiveSessionID(); // 在服务进程下创建子进程; BOOL ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitResult); public: // 初始脚本运行参数; bool InitScript( std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType = EMBEDDED); // 运行脚本; bool StartScript(); // 停止脚本; void StopScript(); // 脚本是否结束; bool IsScriptOver(); // 运行类型; int GetRunType() const { return m_nRunType;} // 获取脚本Id; DWORD GetScriptId() const { if ( m_nRunType == SUBPROCESS ) return m_dwSubprocessId; else return m_dwThreadId; } // 设置用例对象; void SetCaseObje(SATHTTP::STCase *pObj){ m_pCaseObj = pObj;} // 结束子进程; BOOL EndSubprocess(); // 获取活动的CPU时间; ULONGLONG GetActiveTickCount() const { return m_ulStartTickCount;} }; #endif // __SCRIPT_EXECUTOR__