Browse Source

使用以下方法,并不能输出printf的内容:

// 创建stdout的管道;
if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0))
{
	printf("Error:创建stdout管道失败\n");
	return -1;
}

int wpfd = _open_osfhandle((intptr_t)m_hStdOutWrite, 0);
if (_dup2(wpfd, _fileno(stdout)) != 0)
{
	printf("Error:dup2调用失败");
}
_close(wpfd);

if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite))
{
	printf("Error:重定向失败\n");
}
scbc.sat2 5 years ago
parent
commit
c3ee98d735

+ 1 - 1
RunPython/RunPython/Global.cpp

@@ -189,7 +189,7 @@ namespace Global
 		TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
 		_tsetlocale(LC_CTYPE, _T("chs")); //设定中文;
 		//_ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year + 1990, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, msg);
-		_ftprintf(fp,msg);
+		_ftprintf(fp, _T("%s"), msg);
 		// 关闭文件,释放资源并设置回原语言区域;
 		fclose(fp);
 		_tsetlocale(LC_CTYPE, old_locale);

+ 2 - 11
RunPython/RunPython/RunPython.cpp

@@ -32,25 +32,16 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	else
 	{
 		// TODO: 在此处为应用程序的行为编写代码。
-		//RunPython("E:\\bin\\ScbcCopyKey\\test.py"); // 加载失败,但改成test2.py后,就能加载成功
-		//RunPythonEx("E:\\bin\\ScbcCopyKey\\ScbcTest.py", NULL);
-		//RunPythonEx("D:\\SAT\\runner\\btc_runner_se\\runner\\output\\ODF_NPI_RT2841\\20191119172310094\\192.168.1.119_5555\\cases\\RT_2841\\ODF_NPI_RT2841\\picture\\22.py", NULL);
-		//Sleep(10000);
-		//printf("\n\n\n\n=================================================================\n\n");
-		//CallPythonEx("D:\\SAT\\runner\\btc_runner_se\\runner\\output\\ODF_NPI_RT2841\\20191119172310094\\192.168.1.119_5555\\cases\\RT_2841\\ODF_NPI_RT2841\\picture\\22.py", NULL);
-		//CallPythonEx("E:\\bin\\ScbcCopyKey\\ScbcTest.py", NULL);
-		//printf("\n\n\n\n=================================================================\n\n");
-#if 1
 		CScriptExecutor excutor;
 		excutor.InitScript("E:\\bin\\ScbcCopyKey\\ScbcTest.py", 
 			"D:\\SAT\\log.txt", 
 			"",
-			PY_RUN_TYPE::SUBPROCESS);
+			EMBEDDED);
 		excutor.StartScript();
 
+		Sleep(500);
 		while( !excutor.IsScriptOver() )
 			Sleep(100);
-#endif
 	}
 
 	system("pause");

+ 73 - 23
RunPython/RunPython/ScriptExecutor.cpp

@@ -1,6 +1,7 @@
 #include "StdAfx.h"
 #include "ScriptExecutor.h"
 #include <fstream>
+#include <io.h>
 
 CScriptExecutor::CScriptExecutor(void)
 {
@@ -39,11 +40,13 @@ DWORD __stdcall CScriptExecutor::_WorkerThread(LPVOID lpParam)
 		return -1;
 	}
 
-	if ( that->m_nRunType == PY_RUN_TYPE::EMBEDDED )
+	if ( that->m_nRunType == EMBEDDED )
 	{
+		that->RedirectStdout();
+		ResumeThread(that->m_hLogThread);
 		that->RunEmbeddedScript();
 	}
-	else if (that->m_nRunType == PY_RUN_TYPE::SUBPROCESS)
+	else if (that->m_nRunType == SUBPROCESS)
 	{
 		that->RunScripProcess();
 	}
@@ -51,8 +54,8 @@ DWORD __stdcall CScriptExecutor::_WorkerThread(LPVOID lpParam)
 	CloseHandle(that->m_hWorkThread);
 	that->m_hWorkThread = NULL;
 
-	// 线程结束后,应该回调一个通知函数;
-	// ...
+	// 结束日志线程;
+	that->m_bStopLogExport = TRUE;
 
 	return 0;
 }
@@ -66,12 +69,11 @@ DWORD __stdcall CScriptExecutor::_LogExportThread(LPVOID lpParam)
 		return -1;
 	}
 
-	if (that->m_nRunType == PY_RUN_TYPE::SUBPROCESS)
+	if (that->m_nRunType == SUBPROCESS)
 	{
-		DWORD dwRead, dwWritten;
+		DWORD dwRead;
 		CHAR chBuf[BUFSIZE] = {0};
 		BOOL bSuccess = FALSE;
-		HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 		
 		do
 		{
@@ -83,23 +85,46 @@ DWORD __stdcall CScriptExecutor::_LogExportThread(LPVOID lpParam)
 			memset(chBuf, 0, BUFSIZE);
 		} while (!that->m_bStopLogExport);
 	}
-	else if ( that->m_nRunType == PY_RUN_TYPE::EMBEDDED)
+	else if ( that->m_nRunType == EMBEDDED)
 	{
+		DWORD dwRead;
+		CHAR chBuf[BUFSIZE] = {0};
+		BOOL bSuccess = FALSE;
+
 		do
-		{
-			Sleep(20);
+		{	
+			bSuccess = ReadFile(that->m_hStdOutRead, chBuf, BUFSIZE, &dwRead, NULL);
+			if (!bSuccess || dwRead == 0) 
+				continue;
+
+			Global::WritePythonLog(that->m_szLogPath, chBuf);
+			memset(chBuf, 0, BUFSIZE);
 		} while (!that->m_bStopLogExport);
 	}
 
+	// 关闭线程句柄;
 	CloseHandle(that->m_hLogThread);
 	that->m_hLogThread = NULL;
 
+	// 关闭重定向句柄;
+	if (that->m_hStdErrorWrite)
+		CloseHandle(that->m_hStdErrorWrite);
+	that->m_hStdErrorWrite = NULL;
+
+	if (that->m_hStdOutWrite)
+		CloseHandle(that->m_hStdOutWrite);
+	that->m_hStdOutWrite = NULL;
+
+	if (that->m_hStdOutRead)
+		CloseHandle(that->m_hStdOutRead);
+	that->m_hStdOutRead = NULL;
+
 	return 0;
 }
 
-int CScriptExecutor::RedirectStdout(STARTUPINFO& si)
+int CScriptExecutor::RedirectStdout(LPSTARTUPINFO si /*=NULL*/)
 {
-	if (m_nRunType == PY_RUN_TYPE::SUBPROCESS)
+	if (m_nRunType == SUBPROCESS)
 	{
 		SECURITY_ATTRIBUTES sa;
 		sa.bInheritHandle = TRUE;
@@ -120,17 +145,40 @@ int CScriptExecutor::RedirectStdout(STARTUPINFO& si)
 			return -2;
 		}
 
-		si.dwFlags |= STARTF_USESTDHANDLES;
+		si->dwFlags |= STARTF_USESTDHANDLES;
 		// 将子进程的stdout输出到句柄hStdOutWrite;
-		si.hStdOutput = m_hStdOutWrite;
+		si->hStdOutput = m_hStdOutWrite;
 		// 将子进程的stderr输出到句柄hStdErrWrite;
-		si.hStdError = m_hStdErrorWrite;
+		si->hStdError = m_hStdErrorWrite;
 
 		return 0;
 	}
-	else if (m_nRunType == PY_RUN_TYPE::EMBEDDED)
+	else if (m_nRunType == EMBEDDED)
 	{
-		return -1;
+#if 0 // 无法实现转发;
+		FILE *stream;
+		if((stream = freopen(m_szLogPath, "w", stdout)) == NULL)
+			return -1;
+#else
+		// 创建stdout的管道;
+		if (!CreatePipe(&m_hStdOutRead, &m_hStdOutWrite, NULL, 0))
+		{
+			printf("Error:创建stdout管道失败\n");
+			return -1;
+		}
+
+		int wpfd = _open_osfhandle((intptr_t)m_hStdOutWrite, 0);
+		if (_dup2(wpfd, _fileno(stdout)) != 0) 
+		{
+			printf("Error:dup2调用失败");
+		}
+		_close(wpfd);
+
+		if (!SetStdHandle(STD_OUTPUT_HANDLE, m_hStdOutWrite))
+		{
+			printf("Error:重定向失败\n");
+		}
+#endif
 	}
 
 	// 异常类型;
@@ -334,7 +382,7 @@ int CScriptExecutor::RunScripProcess()
 		_stprintf_s(szCommandLine, _T("python -W ignore %s"), m_szScriptPath);
 
 	// 重定向输出;
-	RedirectStdout(m_si);
+	RedirectStdout(&m_si);
 	// 恢复日志线程;
 	ResumeThread(m_hLogThread);
 
@@ -467,9 +515,9 @@ void CScriptExecutor::EndThread(HANDLE hThread, HANDLE hEvent)
 	hEvent = NULL;
 }
 
-bool CScriptExecutor::EndSubprocess()
+BOOL CScriptExecutor::EndSubprocess()
 {
-	bool ret = false;
+	BOOL ret = false;
 	if (m_pi.hProcess)
 	{
 		// 尝试5次结束;
@@ -529,6 +577,8 @@ bool CScriptExecutor::StartScript()
 			printf("Error:日志导出线程创建出错\n");
 		}
 
+		Sleep(100);
+
 		return true;
 	}
 
@@ -541,7 +591,7 @@ bool CScriptExecutor::StartScript()
 void CScriptExecutor::StopScript()
 {
 	// 如果是子进程运行脚本,停止线程时kill进程;
-	if (m_nRunType == PY_RUN_TYPE::SUBPROCESS)
+	if (m_nRunType == SUBPROCESS)
 		EndSubprocess();
 
 	// 结束线程;
@@ -550,12 +600,12 @@ void CScriptExecutor::StopScript()
 
 bool CScriptExecutor::IsScriptOver()
 {
-	if (m_nRunType == PY_RUN_TYPE::EMBEDDED)
+	if (m_nRunType == EMBEDDED)
 	{
 		if ( m_hWorkThread == NULL )
 			return true;
 	}
-	else if (m_nRunType == PY_RUN_TYPE::SUBPROCESS)
+	else if (m_nRunType == SUBPROCESS)
 	{
 		if ( m_pi.hProcess == NULL && m_hWorkThread == NULL )
 			return true;

+ 3 - 3
RunPython/RunPython/ScriptExecutor.h

@@ -43,7 +43,7 @@ protected:
 	// 日志导出线程;
 	static DWORD WINAPI _LogExportThread(LPVOID lpParam);
 	// 重定向标准输出;
-	int RedirectStdout(STARTUPINFO& si);
+	int RedirectStdout(LPSTARTUPINFO si = NULL);
 	// 获取Python异常;
 	void CatchPythonException();
 	// 运行嵌入的脚本;
@@ -58,7 +58,7 @@ protected:
 	void EndLogThread();
 	void EndThread(HANDLE hThread, HANDLE hEvent);
 	// 结束子进程;
-	bool EndSubprocess();
+	BOOL EndSubprocess();
 	// 从管道读取日志;
 	void ReadFromPipe();
 public:
@@ -67,7 +67,7 @@ public:
 		std::string strScript, 
 		std::string strLogPath, 
 		std::string strScriptCmd, 
-		int nRunType = PY_RUN_TYPE::EMBEDDED);
+		int nRunType = EMBEDDED);
 	// 运行脚本;
 	bool StartScript();
 	// 停止脚本;