|
@@ -147,23 +147,20 @@ int CScriptExecutor::RedirectSubprocessStdout(LPSTARTUPINFO si /*=NULL*/)
|
|
|
#endif
|
|
|
|
|
|
// Python脚本中,必须使用sys.__stdout__()
|
|
|
- if (m_nRunType == SUBPROCESS)
|
|
|
- {
|
|
|
+ if (m_nRunType == SUBPROCESS) {
|
|
|
SECURITY_ATTRIBUTES sa;
|
|
|
sa.bInheritHandle = TRUE;
|
|
|
sa.lpSecurityDescriptor = NULL;
|
|
|
sa.nLength = sizeof(sa);
|
|
|
|
|
|
// 创建stdout的管道;
|
|
|
- if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, &sa, 0))
|
|
|
- {
|
|
|
+ if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, &sa, 0)) {
|
|
|
OutputDebugString("Error:创建stdout管道失败\n");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
// 创建stderr的管道,由于stderr一般就是stdout,直接复制句柄;
|
|
|
- if (!DuplicateHandle(GetCurrentProcess(), m_hStdOutWrite, GetCurrentProcess(), &m_hStdErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
|
|
- {
|
|
|
+ if (!DuplicateHandle(GetCurrentProcess(), m_hStdOutWrite, GetCurrentProcess(), &m_hStdErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
|
|
|
OutputDebugString("创建stderr管道失败\n");
|
|
|
return -2;
|
|
|
}
|
|
@@ -188,11 +185,9 @@ int CScriptExecutor::RedirectProcessStdout()
|
|
|
#ifdef _DEBUG
|
|
|
OutputDebugString("RedirectProcessStdout\n");
|
|
|
#endif
|
|
|
- if (m_nRunType == EMBEDDED)
|
|
|
- {
|
|
|
+ if (m_nRunType == EMBEDDED) {
|
|
|
// 创建stdout的管道;
|
|
|
- if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0))
|
|
|
- {
|
|
|
+ if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0)) {
|
|
|
printf("Error:创建stdout管道失败\n");
|
|
|
return -1;
|
|
|
}
|
|
@@ -200,8 +195,7 @@ int CScriptExecutor::RedirectProcessStdout()
|
|
|
// 将 C 运行时文件描述符与现有操作系统文件句柄关联;
|
|
|
int wpfd = _open_osfhandle((intptr_t)m_hStdOutWrite, _O_TEXT);
|
|
|
// 为stdout分配新文件描述符;
|
|
|
- if (_dup2(wpfd, _fileno(stdout)) != 0)
|
|
|
- {
|
|
|
+ if (_dup2(wpfd, _fileno(stdout)) != 0) {
|
|
|
printf("Error:dup2调用失败");
|
|
|
return -2;
|
|
|
}
|
|
@@ -210,8 +204,7 @@ int CScriptExecutor::RedirectProcessStdout()
|
|
|
// 备份进程原始标准输出;
|
|
|
m_hOldStdOutWrite = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
// 设备进程标准输出,重定向到管道中;
|
|
|
- if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite))
|
|
|
- {
|
|
|
+ if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite)) {
|
|
|
printf("Error:重定向失败\n");
|
|
|
return -3;
|
|
|
}
|
|
@@ -252,17 +245,14 @@ void CScriptExecutor::CatchPythonException()
|
|
|
// 非控制台,使用PyErr_Fetch捕获异常;
|
|
|
PyErr_Fetch(&pPyType, &pPyValue, &pPyTraceback);
|
|
|
PyErr_NormalizeException(&pPyType, &pPyValue, &pPyTraceback); // 可有可无,不影响获取异常;
|
|
|
- if (pPyValue)
|
|
|
- {
|
|
|
+ if (pPyValue) {
|
|
|
PyObject* pPyStr = PyObject_Str(pPyValue);
|
|
|
- if (PyString_Check(pPyStr))
|
|
|
- {
|
|
|
+ if (PyString_Check(pPyStr)) {
|
|
|
pszErrMsg = PyString_AsString(pPyStr);
|
|
|
if (pszErrMsg)
|
|
|
printf("Error Info=>%s\n", pszErrMsg);
|
|
|
|
|
|
- if (pPyTraceback)
|
|
|
- {
|
|
|
+ if (pPyTraceback) {
|
|
|
PyObject* pPyTraceModule = PyImport_ImportModule("traceback");
|
|
|
if (!pPyTraceModule)
|
|
|
{
|
|
@@ -271,21 +261,17 @@ void CScriptExecutor::CatchPythonException()
|
|
|
}
|
|
|
#if 1 // 细分出所有换行符;
|
|
|
PyObject* pPyModuleDict = PyModule_GetDict(pPyTraceModule);
|
|
|
- if (pPyModuleDict)
|
|
|
- {
|
|
|
+ if (pPyModuleDict) {
|
|
|
PyObject* pPyFunc = PyDict_GetItemString(pPyModuleDict, "format_exception");
|
|
|
- if (!pPyFunc || !PyCallable_Check(pPyFunc))
|
|
|
- {
|
|
|
+ if (!pPyFunc || !PyCallable_Check(pPyFunc)) {
|
|
|
printf("Error:加载format_exception失败\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
PyObject* pErroList = PyObject_CallFunctionObjArgs(pPyFunc, pPyType, pPyValue, pPyTraceback, NULL);
|
|
|
- if (pErroList)
|
|
|
- {
|
|
|
+ if (pErroList) {
|
|
|
int nSize = PyList_Size(pErroList);
|
|
|
- for (int i = 0; i < nSize; i++)
|
|
|
- {
|
|
|
+ for (int i = 0; i < nSize; i++) {
|
|
|
pszErrMsg = PyString_AsString(PyList_GetItem(pErroList, i));
|
|
|
printf("%s", pszErrMsg);
|
|
|
}
|
|
@@ -323,8 +309,7 @@ void CScriptExecutor::CatchPythonException()
|
|
|
int CScriptExecutor::RunEmbeddedScript()
|
|
|
{
|
|
|
// 参数有效性判断;
|
|
|
- if (!PathFileExists(m_szScriptPath))
|
|
|
- {
|
|
|
+ if (!PathFileExists(m_szScriptPath)) {
|
|
|
printf("Error:脚本文件不存在\n");
|
|
|
return -1;
|
|
|
}
|
|
@@ -333,8 +318,7 @@ int CScriptExecutor::RunEmbeddedScript()
|
|
|
if (!Py_IsInitialized())
|
|
|
Py_Initialize();
|
|
|
|
|
|
- if (!Py_IsInitialized())
|
|
|
- {
|
|
|
+ if (!Py_IsInitialized()) {
|
|
|
printf("Error:初始化Python环境失败\n");
|
|
|
return -2;
|
|
|
}
|
|
@@ -352,8 +336,7 @@ int CScriptExecutor::RunEmbeddedScript()
|
|
|
scriptdir = szScriptDir;
|
|
|
// 将'\'转换成'/', Python才设置运行目录成功;
|
|
|
int len = _tcslen(szScriptDir);
|
|
|
- for (int i = 0; i < len; i++)
|
|
|
- {
|
|
|
+ for (int i = 0; i < len; i++) {
|
|
|
if (szScriptDir[i] == '\\')
|
|
|
szScriptDir[i] = '/';
|
|
|
}
|
|
@@ -489,8 +472,7 @@ int CScriptExecutor::RunScriptProcess()
|
|
|
|
|
|
int CScriptExecutor::ServiceRunScriptProcess()
|
|
|
{
|
|
|
- if (!PathFileExists(m_szScriptPath))
|
|
|
- {
|
|
|
+ if (!PathFileExists(m_szScriptPath)) {
|
|
|
printf("Error:脚本路径无效\n");
|
|
|
return -1;
|
|
|
}
|
|
@@ -501,26 +483,20 @@ int CScriptExecutor::ServiceRunScriptProcess()
|
|
|
DWORD dwSid = GetActiveSessionID();
|
|
|
|
|
|
HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
|
|
|
- if (!WTSQueryUserToken(dwSid, &hPToken))
|
|
|
- {
|
|
|
+ if (!WTSQueryUserToken(dwSid, &hPToken)) {
|
|
|
PROCESSENTRY32 procEntry;
|
|
|
DWORD dwPid = 0;
|
|
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
- if (hSnap == INVALID_HANDLE_VALUE)
|
|
|
- {
|
|
|
+ if (hSnap == INVALID_HANDLE_VALUE) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
procEntry.dwSize = sizeof(PROCESSENTRY32);
|
|
|
- if (Process32First(hSnap, &procEntry))
|
|
|
- {
|
|
|
- do
|
|
|
- {
|
|
|
- if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0)
|
|
|
- {
|
|
|
+ if (Process32First(hSnap, &procEntry)) {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0) {
|
|
|
DWORD exeSessionId = 0;
|
|
|
- if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid)
|
|
|
- {
|
|
|
+ if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid) {
|
|
|
dwPid = procEntry.th32ProcessID;
|
|
|
break;
|
|
|
}
|
|
@@ -531,19 +507,16 @@ int CScriptExecutor::ServiceRunScriptProcess()
|
|
|
CloseHandle(hSnap);
|
|
|
|
|
|
// explorer进程不存在
|
|
|
- if (dwPid == 0)
|
|
|
- {
|
|
|
+ if (dwPid == 0) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
|
|
|
- if (hProcess == NULL)
|
|
|
- {
|
|
|
+ if (hProcess == NULL) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
- if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken))
|
|
|
- {
|
|
|
+ if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken)) {
|
|
|
CloseHandle(hProcess);
|
|
|
return FALSE;
|
|
|
}
|
|
@@ -555,20 +528,16 @@ int CScriptExecutor::ServiceRunScriptProcess()
|
|
|
TOKEN_LINKED_TOKEN admin;
|
|
|
bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
|
|
|
|
|
|
- if (!bResult) // vista 以前版本不支持TokenLinkedToken
|
|
|
- {
|
|
|
+ if (!bResult) {// vista 以前版本不支持TokenLinkedToken
|
|
|
TOKEN_PRIVILEGES tp;
|
|
|
LUID luid;
|
|
|
- if (LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&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
|
|
|
- {
|
|
|
+ } else {
|
|
|
hUserTokenDup = admin.LinkedToken;
|
|
|
}
|
|
|
|
|
@@ -658,16 +627,14 @@ bool CScriptExecutor::StartThread()
|
|
|
{
|
|
|
// 创建线程;
|
|
|
m_hWorkThread = CreateThread(NULL, 0, _WorkerThread, this, 0, &m_dwThreadId);
|
|
|
- if (!m_hWorkThread)
|
|
|
- {
|
|
|
+ if (!m_hWorkThread) {
|
|
|
printf("Error:创建执行线程失败\n");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 创建线程;
|
|
|
m_hLogThread = CreateThread(NULL, 0, _LogExportThread, this, CREATE_SUSPENDED, NULL);
|
|
|
- if (!m_hLogThread)
|
|
|
- {
|
|
|
+ if (!m_hLogThread) {
|
|
|
printf("Error:创建日志线程失败\n");
|
|
|
return false;
|
|
|
}
|
|
@@ -735,11 +702,9 @@ void CScriptExecutor::EndThread()
|
|
|
BOOL CScriptExecutor::EndSubprocess()
|
|
|
{
|
|
|
BOOL ret = false;
|
|
|
- if (m_pi.hProcess)
|
|
|
- {
|
|
|
+ if (m_pi.hProcess) {
|
|
|
// 尝试5次结束;
|
|
|
- for (int i = 0; i < 5; i++)
|
|
|
- {
|
|
|
+ for (int i = 0; i < 5; i++) {
|
|
|
if ( (ret = TerminateProcess(m_pi.hProcess, 0)) )
|
|
|
break;
|
|
|
}
|
|
@@ -815,11 +780,9 @@ DWORD CScriptExecutor::GetActiveSessionID()
|
|
|
|
|
|
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
|
|
|
|
|
|
- for(DWORD i = 0; i < dwCount; i++)
|
|
|
- {
|
|
|
+ for(DWORD i = 0; i < dwCount; i++) {
|
|
|
WTS_SESSION_INFO si = pSessionInfo[i];
|
|
|
- if(WTSActive == si.State)
|
|
|
- {
|
|
|
+ if(WTSActive == si.State) {
|
|
|
dwSessionId = si.SessionId;
|
|
|
break;
|
|
|
}
|
|
@@ -843,27 +806,20 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
PROCESS_INFORMATION pi;
|
|
|
STARTUPINFO si;
|
|
|
HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
|
|
|
- if (!WTSQueryUserToken(dwSid, &hPToken))
|
|
|
- {
|
|
|
- ofile<<"get token error 1"<<std::endl;
|
|
|
+ if (!WTSQueryUserToken(dwSid, &hPToken)) {
|
|
|
PROCESSENTRY32 procEntry;
|
|
|
DWORD dwPid = 0;
|
|
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
- if (hSnap == INVALID_HANDLE_VALUE)
|
|
|
- {
|
|
|
+ if (hSnap == INVALID_HANDLE_VALUE) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
procEntry.dwSize = sizeof(PROCESSENTRY32);
|
|
|
- if (Process32First(hSnap, &procEntry))
|
|
|
- {
|
|
|
- do
|
|
|
- {
|
|
|
- if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0)
|
|
|
- {
|
|
|
+ if (Process32First(hSnap, &procEntry)) {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0) {
|
|
|
DWORD exeSessionId = 0;
|
|
|
- if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid)
|
|
|
- {
|
|
|
+ if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid) {
|
|
|
dwPid = procEntry.th32ProcessID;
|
|
|
break;
|
|
|
}
|
|
@@ -880,13 +836,11 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
}
|
|
|
|
|
|
hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
|
|
|
- if (hProcess == NULL)
|
|
|
- {
|
|
|
+ if (hProcess == NULL) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
- if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken))
|
|
|
- {
|
|
|
+ if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken)) {
|
|
|
CloseHandle(hProcess);
|
|
|
return FALSE;
|
|
|
}
|
|
@@ -898,21 +852,16 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
TOKEN_LINKED_TOKEN admin;
|
|
|
bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
|
|
|
|
|
|
- if (!bResult) // vista 以前版本不支持TokenLinkedToken
|
|
|
- {
|
|
|
- ofile<<"Get token info error" <<std::endl;
|
|
|
+ if (!bResult) {// vista 以前版本不支持TokenLinkedToken
|
|
|
TOKEN_PRIVILEGES tp;
|
|
|
LUID luid;
|
|
|
- if (LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&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
|
|
|
- {
|
|
|
+ } else {
|
|
|
hUserTokenDup = admin.LinkedToken;
|
|
|
ofile<<"token: "<<hUserTokenDup<<std::endl;
|
|
|
}
|
|
@@ -920,12 +869,9 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
LPVOID pEnv =NULL;
|
|
|
DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
|
|
|
|
|
|
- if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
|
|
|
- {
|
|
|
+ if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE)) {
|
|
|
dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
pEnv = NULL;
|
|
|
}
|
|
|
|
|
@@ -937,45 +883,36 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
|
|
|
bResult = CreateProcessAsUser(
|
|
|
hUserTokenDup, // client's access token
|
|
|
- NULL, // file to execute
|
|
|
+ NULL, // file to execute
|
|
|
(LPTSTR) wstrCmdLine.c_str(), // command line
|
|
|
- NULL, // pointer to process SECURITY_ATTRIBUTES
|
|
|
- NULL, // pointer to thread SECURITY_ATTRIBUTES
|
|
|
- FALSE, // handles are not inheritable
|
|
|
- dwCreationFlags, // creation flags
|
|
|
- pEnv, // pointer to new environment block
|
|
|
- NULL, // name of current directory
|
|
|
- &si, // pointer to STARTUPINFO structure
|
|
|
- &pi // receives information about new process
|
|
|
+ NULL, // pointer to process SECURITY_ATTRIBUTES
|
|
|
+ NULL, // pointer to thread SECURITY_ATTRIBUTES
|
|
|
+ FALSE, // handles are not inheritable
|
|
|
+ dwCreationFlags, // creation flags
|
|
|
+ pEnv, // pointer to new environment block
|
|
|
+ NULL, // name of current directory
|
|
|
+ &si, // pointer to STARTUPINFO structure
|
|
|
+ &pi // receives information about new process
|
|
|
);
|
|
|
|
|
|
- if(pi.hProcess)
|
|
|
- {
|
|
|
- if(WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 180000))
|
|
|
- {
|
|
|
+ if(pi.hProcess) {
|
|
|
+ if(WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 180000)) {
|
|
|
DWORD dwResult = 0;
|
|
|
- if(GetExitCodeProcess(pi.hProcess, &dwResult))
|
|
|
- {
|
|
|
+ if(GetExitCodeProcess(pi.hProcess, &dwResult)) {
|
|
|
n32ExitResult = dwResult;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
n32ExitResult = -1;
|
|
|
}
|
|
|
|
|
|
CloseHandle(pi.hThread);
|
|
|
CloseHandle(pi.hProcess);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
CloseHandle(pi.hThread);
|
|
|
CloseHandle(pi.hProcess);
|
|
|
n32ExitResult = -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
if (hUserTokenDup != NULL)
|
|
|
CloseHandle(hUserTokenDup);
|
|
|
if (hProcess != NULL)
|
|
@@ -992,26 +929,22 @@ BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitRes
|
|
|
bool CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
|
|
|
{
|
|
|
// 判断脚本是否存在;
|
|
|
- if (!PathFileExists(strScript.c_str()))
|
|
|
- {
|
|
|
+ if (!PathFileExists(strScript.c_str())) {
|
|
|
printf("Error:脚本文件不存在\n");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 判断日志文件路径是否可创建;
|
|
|
- if (!PathFileExists(strLogPath.c_str()))
|
|
|
- {
|
|
|
+ if (!PathFileExists(strLogPath.c_str())) {
|
|
|
// 创建路径;
|
|
|
- if (!GLOBAL::MKDIR(strLogPath.c_str()))
|
|
|
- {
|
|
|
+ if (!GLOBAL::MKDIR(strLogPath.c_str())) {
|
|
|
printf("Error:创建目录失败\n");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 创建文件;
|
|
|
std::ofstream flog(strLogPath.c_str());
|
|
|
- if ( flog.bad() )
|
|
|
- {
|
|
|
+ if ( flog.bad() ) {
|
|
|
printf("Error:创建文件失败\n");
|
|
|
return false;
|
|
|
}
|