|
@@ -11,18 +11,12 @@
|
|
#include <Userenv.h>
|
|
#include <Userenv.h>
|
|
#pragma comment(lib,"userenv.lib")
|
|
#pragma comment(lib,"userenv.lib")
|
|
|
|
|
|
-
|
|
|
|
-typedef struct _TOKEN_LINKED_TOKEN {
|
|
|
|
-HANDLE LinkedToken;
|
|
|
|
-} TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN;
|
|
|
|
-SERVICE_STATUS_HANDLE hServiceStatus;
|
|
|
|
-*/
|
|
|
|
|
|
|
|
CPythonExecutor::CPythonExecutor(void)
|
|
CPythonExecutor::CPythonExecutor(void)
|
|
{
|
|
{
|
|
m_hWorkThread = NULL;
|
|
m_hWorkThread = NULL;
|
|
m_hStdoutLogThread = NULL;
|
|
m_hStdoutLogThread = NULL;
|
|
- m_bStatus = FALSE;
|
|
+ m_hStderrLogThread = NULL;
|
|
|
|
|
|
m_hStdOutRead = NULL;
|
|
m_hStdOutRead = NULL;
|
|
m_hStdOutWrite = NULL;
|
|
m_hStdOutWrite = NULL;
|
|
@@ -37,10 +31,7 @@ CPythonExecutor::CPythonExecutor(void)
|
|
memset(&m_pi, 0, sizeof(m_pi));
|
|
memset(&m_pi, 0, sizeof(m_pi));
|
|
m_si.cb = sizeof(m_si);
|
|
m_si.cb = sizeof(m_si);
|
|
|
|
|
|
- m_bKillProcess = FALSE;
|
|
|
|
m_bStopLogExport = FALSE;
|
|
m_bStopLogExport = FALSE;
|
|
- m_dwThreadId = 0;
|
|
|
|
- m_dwSubprocessId = 0;
|
|
|
|
|
|
|
|
m_pCaseObj = NULL;
|
|
m_pCaseObj = NULL;
|
|
m_ulStartTickCount = 0;
|
|
m_ulStartTickCount = 0;
|
|
@@ -78,11 +69,6 @@ DWORD CPythonExecutor::_WorkerThread(LPVOID lpParam)
|
|
DWORD CPythonExecutor::_StdoutLogExportThread(LPVOID lpParam)
|
|
DWORD CPythonExecutor::_StdoutLogExportThread(LPVOID lpParam)
|
|
{
|
|
{
|
|
CPythonExecutor* that = (CPythonExecutor*)lpParam;
|
|
CPythonExecutor* that = (CPythonExecutor*)lpParam;
|
|
- if (!that) {
|
|
|
|
- printf("Error:参数失效\n");
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
|
|
DWORD dwRead;
|
|
DWORD dwRead;
|
|
CHAR chBuf[BUFSIZE] = {0};
|
|
CHAR chBuf[BUFSIZE] = {0};
|
|
@@ -102,11 +88,7 @@ DWORD CPythonExecutor::_StdoutLogExportThread(LPVOID lpParam)
|
|
memset(chBuf, 0, BUFSIZE);
|
|
memset(chBuf, 0, BUFSIZE);
|
|
} while (!that->m_bStopLogExport);
|
|
} while (!that->m_bStopLogExport);
|
|
|
|
|
|
-
|
|
+ GLOBAL::WriteTextLog(_T("脚本标准输出日志线程结束,用例名=%s"), that->m_pCaseObj->strCaseName.c_str());
|
|
-
|
|
|
|
-
|
|
|
|
- that->EndSubprocessStdOut();
|
|
|
|
- GLOBAL::WriteTextLog(_T("脚本日志线程结束,用例名=%s"), that->m_pCaseObj->strCaseName.c_str());
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -114,11 +96,6 @@ DWORD CPythonExecutor::_StdoutLogExportThread(LPVOID lpParam)
|
|
DWORD CPythonExecutor::_StderrLogExportThread(LPVOID lpParam)
|
|
DWORD CPythonExecutor::_StderrLogExportThread(LPVOID lpParam)
|
|
{
|
|
{
|
|
CPythonExecutor* that = (CPythonExecutor*)lpParam;
|
|
CPythonExecutor* that = (CPythonExecutor*)lpParam;
|
|
- if (!that) {
|
|
|
|
- printf("Error:参数失效\n");
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
|
|
DWORD dwRead;
|
|
DWORD dwRead;
|
|
CHAR chBuf[BUFSIZE] = {0};
|
|
CHAR chBuf[BUFSIZE] = {0};
|
|
@@ -126,21 +103,18 @@ DWORD CPythonExecutor::_StderrLogExportThread(LPVOID lpParam)
|
|
|
|
|
|
do
|
|
do
|
|
{
|
|
{
|
|
- bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
|
|
+ bSuccess = ReadFile(that->m_hStdErrorRead, chBuf, BUFSIZE, &dwRead, NULL);
|
|
if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
|
|
if (!bSuccess || dwRead == 0 || !_tcslen(chBuf))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- that->m_ulStartTickCount = GetTickCount64();
|
|
|
|
GLOBAL::WritePythonLog(that->m_szLogPath, chBuf);
|
|
GLOBAL::WritePythonLog(that->m_szLogPath, chBuf);
|
|
-
|
|
+ that->m_pCaseObj->_nExecutionState = 4;
|
|
- if ( that->m_pCaseObj )
|
|
|
|
- that->m_pCaseObj->_ulStartTickCount = GetTickCount64();
|
|
|
|
memset(chBuf, 0, BUFSIZE);
|
|
memset(chBuf, 0, BUFSIZE);
|
|
- } while (!that->m_bStopLogExport);
|
|
+ } while (!that->m_bStopLogExport);
|
|
-
|
|
+
|
|
|
|
|
|
that->EndSubprocessStdOut();
|
|
that->EndSubprocessStdOut();
|
|
- GLOBAL::WriteTextLog(_T("脚本日志线程结束,用例名=%s"), that->m_pCaseObj->strCaseName.c_str());
|
|
+ GLOBAL::WriteTextLog(_T("脚本标准错误日志线程结束,用例名=%s"), that->m_pCaseObj->strCaseName.c_str());
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -184,8 +158,7 @@ int CPythonExecutor::RedirectSubprocessStdout(LPSTARTUPINFO si )
|
|
|
|
|
|
int CPythonExecutor::RunScriptProcess()
|
|
int CPythonExecutor::RunScriptProcess()
|
|
{
|
|
{
|
|
- if (!PathFileExists(m_szScriptPath))
|
|
+ if (!PathFileExists(m_szScriptPath)) {
|
|
- {
|
|
|
|
printf("Error:脚本路径无效\n");
|
|
printf("Error:脚本路径无效\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -207,6 +180,7 @@ int CPythonExecutor::RunScriptProcess()
|
|
RedirectSubprocessStdout(&m_si);
|
|
RedirectSubprocessStdout(&m_si);
|
|
|
|
|
|
ResumeThread(m_hStdoutLogThread);
|
|
ResumeThread(m_hStdoutLogThread);
|
|
|
|
+ ResumeThread(m_hStderrLogThread);
|
|
|
|
|
|
|
|
|
|
if (!CreateProcess(
|
|
if (!CreateProcess(
|
|
@@ -226,7 +200,6 @@ int CPythonExecutor::RunScriptProcess()
|
|
return -3;
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
|
|
- m_dwSubprocessId = m_pi.dwProcessId;
|
|
|
|
|
|
|
|
WaitForSingleObject(m_pi.hProcess, INFINITE);
|
|
WaitForSingleObject(m_pi.hProcess, INFINITE);
|
|
|
|
|
|
@@ -345,6 +318,7 @@ int CPythonExecutor::ServiceRunScriptProcess()
|
|
RedirectSubprocessStdout(&m_si);
|
|
RedirectSubprocessStdout(&m_si);
|
|
|
|
|
|
ResumeThread(m_hStdoutLogThread);
|
|
ResumeThread(m_hStdoutLogThread);
|
|
|
|
+ ResumeThread(m_hStderrLogThread);
|
|
|
|
|
|
|
|
|
|
TCHAR szCommandLine[MAX_PATH] = { 0 };
|
|
TCHAR szCommandLine[MAX_PATH] = { 0 };
|
|
@@ -369,8 +343,6 @@ int CPythonExecutor::ServiceRunScriptProcess()
|
|
if ( !bResult )
|
|
if ( !bResult )
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
- m_dwSubprocessId = m_pi.dwProcessId;
|
|
|
|
-
|
|
|
|
|
|
|
|
WaitForSingleObject(m_pi.hProcess, INFINITE);
|
|
WaitForSingleObject(m_pi.hProcess, INFINITE);
|
|
|
|
|
|
@@ -406,20 +378,27 @@ int CPythonExecutor::ServiceRunScriptProcess()
|
|
|
|
|
|
bool CPythonExecutor::StartThread()
|
|
bool CPythonExecutor::StartThread()
|
|
{
|
|
{
|
|
-
|
|
+
|
|
- m_hWorkThread = CreateThread(NULL, 0, _WorkerThread, this, 0, &m_dwThreadId);
|
|
+ m_hWorkThread = CreateThread(NULL, 0, _WorkerThread, this, 0, NULL);
|
|
if (!m_hWorkThread) {
|
|
if (!m_hWorkThread) {
|
|
printf("Error:创建执行线程失败\n");
|
|
printf("Error:创建执行线程失败\n");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
+
|
|
m_hStdoutLogThread = CreateThread(NULL, 0, _StdoutLogExportThread, this, CREATE_SUSPENDED, NULL);
|
|
m_hStdoutLogThread = CreateThread(NULL, 0, _StdoutLogExportThread, this, CREATE_SUSPENDED, NULL);
|
|
if (!m_hStdoutLogThread) {
|
|
if (!m_hStdoutLogThread) {
|
|
printf("Error:创建日志线程失败\n");
|
|
printf("Error:创建日志线程失败\n");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ m_hStderrLogThread = CreateThread(NULL, 0, _StderrLogExportThread, this, CREATE_SUSPENDED, NULL);
|
|
|
|
+ if (!m_hStderrLogThread) {
|
|
|
|
+ printf("Error:创建日志线程失败\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -451,13 +430,13 @@ void CPythonExecutor::EndWorkThread()
|
|
|
|
|
|
void CPythonExecutor::EndLogThread()
|
|
void CPythonExecutor::EndLogThread()
|
|
{
|
|
{
|
|
|
|
+
|
|
m_bStopLogExport = TRUE;
|
|
m_bStopLogExport = TRUE;
|
|
|
|
|
|
if ( m_hStdoutLogThread ) {
|
|
if ( m_hStdoutLogThread ) {
|
|
if ( WaitForSingleObject(m_hStdoutLogThread, 3000) == WAIT_OBJECT_0 ) {
|
|
if ( WaitForSingleObject(m_hStdoutLogThread, 3000) == WAIT_OBJECT_0 ) {
|
|
CloseHandle(m_hStdoutLogThread);
|
|
CloseHandle(m_hStdoutLogThread);
|
|
m_hStdoutLogThread = NULL;
|
|
m_hStdoutLogThread = NULL;
|
|
- return;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -472,6 +451,26 @@ void CPythonExecutor::EndLogThread()
|
|
CloseHandle(m_hStdoutLogThread);
|
|
CloseHandle(m_hStdoutLogThread);
|
|
m_hStdoutLogThread = NULL;
|
|
m_hStdoutLogThread = NULL;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if ( m_hStderrLogThread ) {
|
|
|
|
+ if ( WaitForSingleObject(m_hStderrLogThread, 3000) == WAIT_OBJECT_0 ) {
|
|
|
|
+ CloseHandle(m_hStderrLogThread);
|
|
|
|
+ m_hStderrLogThread = NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (m_hStderrLogThread) {
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < 5; i++) {
|
|
|
|
+ if (TerminateThread(m_hStderrLogThread, 0))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CloseHandle(m_hStderrLogThread);
|
|
|
|
+ m_hStderrLogThread = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void CPythonExecutor::EndThread()
|
|
void CPythonExecutor::EndThread()
|
|
@@ -496,8 +495,12 @@ BOOL CPythonExecutor::EndSubprocess()
|
|
|
|
|
|
void CPythonExecutor::EndSubprocessStdOut()
|
|
void CPythonExecutor::EndSubprocessStdOut()
|
|
{
|
|
{
|
|
- OutputDebugString("--------------EndSubprocessStdOut----------------\n");
|
|
+ OutputDebugString("关闭重定向子进程标准输出管道句柄\n");
|
|
|
|
|
|
|
|
+ if (m_hStdErrorRead)
|
|
|
|
+ CloseHandle(m_hStdErrorRead);
|
|
|
|
+ m_hStdErrorRead = NULL;
|
|
|
|
+
|
|
if (m_hStdErrorWrite)
|
|
if (m_hStdErrorWrite)
|
|
CloseHandle(m_hStdErrorWrite);
|
|
CloseHandle(m_hStdErrorWrite);
|
|
m_hStdErrorWrite = NULL;
|
|
m_hStdErrorWrite = NULL;
|
|
@@ -533,139 +536,6 @@ DWORD CPythonExecutor::GetActiveSessionID()
|
|
return dwSessionId;
|
|
return dwSessionId;
|
|
}
|
|
}
|
|
|
|
|
|
-BOOL CPythonExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitResult)
|
|
|
|
-{
|
|
|
|
- ofstream ofile("C:\\logEvent.txt");
|
|
|
|
- ofile<<"start excute"<<std::endl;
|
|
|
|
- DWORD dwProcesses = 0;
|
|
|
|
- BOOL bResult = FALSE;
|
|
|
|
-
|
|
|
|
- DWORD dwSid = GetActiveSessionID();
|
|
|
|
-
|
|
|
|
- DWORD dwRet = 0;
|
|
|
|
- PROCESS_INFORMATION pi;
|
|
|
|
- STARTUPINFO si;
|
|
|
|
- HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
|
|
|
|
- if (!WTSQueryUserToken(dwSid, &hPToken)) {
|
|
|
|
- PROCESSENTRY32 procEntry;
|
|
|
|
- DWORD dwPid = 0;
|
|
|
|
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
|
- if (hSnap == INVALID_HANDLE_VALUE) {
|
|
|
|
- return FALSE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- procEntry.dwSize = sizeof(PROCESSENTRY32);
|
|
|
|
- if (Process32First(hSnap, &procEntry)) {
|
|
|
|
- do {
|
|
|
|
- if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0) {
|
|
|
|
- DWORD exeSessionId = 0;
|
|
|
|
- if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid) {
|
|
|
|
- dwPid = procEntry.th32ProcessID;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } while (Process32Next(hSnap, &procEntry));
|
|
|
|
- }
|
|
|
|
- CloseHandle(hSnap);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- if (dwPid == 0)
|
|
|
|
- {
|
|
|
|
- return FALSE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
|
|
|
|
- if (hProcess == NULL) {
|
|
|
|
- return FALSE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken)) {
|
|
|
|
- CloseHandle(hProcess);
|
|
|
|
- return FALSE;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (hPToken == NULL)
|
|
|
|
- return FALSE;
|
|
|
|
-
|
|
|
|
- TOKEN_LINKED_TOKEN admin;
|
|
|
|
- bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
|
|
|
|
-
|
|
|
|
- if (!bResult) {
|
|
|
|
- TOKEN_PRIVILEGES tp;
|
|
|
|
- LUID luid;
|
|
|
|
- if (LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid)) {
|
|
|
|
- tp.PrivilegeCount =1;
|
|
|
|
- tp.Privileges[0].Luid =luid;
|
|
|
|
- tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
|
|
|
|
- }
|
|
|
|
- DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);
|
|
|
|
- } else {
|
|
|
|
- hUserTokenDup = admin.LinkedToken;
|
|
|
|
- ofile<<"token: "<<hUserTokenDup<<std::endl;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- LPVOID pEnv =NULL;
|
|
|
|
- DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
|
|
|
|
-
|
|
|
|
- if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE)) {
|
|
|
|
- dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
|
|
|
|
- } else {
|
|
|
|
- pEnv = NULL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ZeroMemory( &si, sizeof(si) );
|
|
|
|
- si.cb = sizeof(si);
|
|
|
|
- si.dwFlags = STARTF_USESHOWWINDOW;
|
|
|
|
- si.wShowWindow = SW_SHOWNORMAL;
|
|
|
|
- ZeroMemory( &pi, sizeof(pi) );
|
|
|
|
-
|
|
|
|
- bResult = CreateProcessAsUser(
|
|
|
|
- hUserTokenDup,
|
|
|
|
- NULL,
|
|
|
|
- (LPTSTR) wstrCmdLine.c_str(),
|
|
|
|
- NULL,
|
|
|
|
- NULL,
|
|
|
|
- FALSE,
|
|
|
|
- dwCreationFlags,
|
|
|
|
- pEnv,
|
|
|
|
- NULL,
|
|
|
|
- &si,
|
|
|
|
- &pi
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- if(pi.hProcess) {
|
|
|
|
- if(WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 180000)) {
|
|
|
|
- DWORD dwResult = 0;
|
|
|
|
- if(GetExitCodeProcess(pi.hProcess, &dwResult)) {
|
|
|
|
- n32ExitResult = dwResult;
|
|
|
|
- } else {
|
|
|
|
- n32ExitResult = -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CloseHandle(pi.hThread);
|
|
|
|
- CloseHandle(pi.hProcess);
|
|
|
|
- } else {
|
|
|
|
- CloseHandle(pi.hThread);
|
|
|
|
- CloseHandle(pi.hProcess);
|
|
|
|
- n32ExitResult = -1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (hUserTokenDup != NULL)
|
|
|
|
- CloseHandle(hUserTokenDup);
|
|
|
|
- if (hProcess != NULL)
|
|
|
|
- CloseHandle(hProcess);
|
|
|
|
- if (hPToken != NULL)
|
|
|
|
- CloseHandle(hPToken);
|
|
|
|
- if (pEnv != NULL)
|
|
|
|
- DestroyEnvironmentBlock(pEnv);
|
|
|
|
-
|
|
|
|
- return TRUE;
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
bool CPythonExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd)
|
|
bool CPythonExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd)
|
|
{
|
|
{
|
|
|
|
|
|
@@ -692,7 +562,6 @@ bool CPythonExecutor::InitScript(std::string strScript, std::string strLogPath,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- m_dwThreadId = m_dwSubprocessId = 0;
|
|
|
|
_tcscpy_s(m_szScriptPath, strScript.c_str());
|
|
_tcscpy_s(m_szScriptPath, strScript.c_str());
|
|
_tcscpy_s(m_szLogPath, strLogPath.c_str());
|
|
_tcscpy_s(m_szLogPath, strLogPath.c_str());
|
|
_tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
|
|
_tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
|
|
@@ -707,9 +576,6 @@ bool CPythonExecutor::StartScript()
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- printf("Error:异常类型脚本\n");
|
|
|
|
-
|
|
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -723,7 +589,9 @@ void CPythonExecutor::StopScript()
|
|
|
|
|
|
bool CPythonExecutor::IsScriptOver()
|
|
bool CPythonExecutor::IsScriptOver()
|
|
{
|
|
{
|
|
- if ( WaitForSingleObject(m_hStdoutLogThread, 0) == WAIT_OBJECT_0 && WaitForSingleObject(m_hWorkThread, 0) == WAIT_OBJECT_0)
|
|
+ if ( WaitForSingleObject(m_hStdoutLogThread, 0) == WAIT_OBJECT_0 &&
|
|
|
|
+ WaitForSingleObject(m_hStderrLogThread, 0) == WAIT_OBJECT_0 &&
|
|
|
|
+ WaitForSingleObject(m_hWorkThread, 0) == WAIT_OBJECT_0)
|
|
{
|
|
{
|
|
GLOBAL::WriteTextLog(_T("====>脚本(%s)已完成"), m_pCaseObj->strCaseName.c_str());
|
|
GLOBAL::WriteTextLog(_T("====>脚本(%s)已完成"), m_pCaseObj->strCaseName.c_str());
|
|
return true;
|
|
return true;
|