Browse Source

1、脚本执行如果不是在用户进程中创建子进程,会导致Python子进程无法正常执行脚本;
2、添加ServiceRunScriptProcess用于在服务进程中执行Python子进程;

scbc.sat2 5 năm trước cách đây
mục cha
commit
3173b2d3e8

+ 268 - 3
SATService/SATService/SATExecutor.cpp

@@ -1,9 +1,10 @@
 #include "StdAfx.h"
 #include "SATExecutor.h"
-
+#include "ScriptExecutor.h"
 
 CSATExecutor::CSATExecutor(void)
 {
+	m_bLogin = FALSE;
 	m_hEventHearbeat = NULL;
 	m_hThreadHearbeat = NULL;
 	m_hEventExcuteScript = NULL;
@@ -17,7 +18,7 @@ CSATExecutor::~CSATExecutor(void)
 bool CSATExecutor::IsTaskExist(SATParameters::STTask &task)
 {
 	bool found = false;
-	std::vector<SATParameters::STTask>::iterator it = m_vtTask.begin();
+	std::list<SATParameters::STTask>::iterator it = m_vtTask.begin();
 	for ( ; it != m_vtTask.end(); it++ )
 	{
 		if ( it->nTaskId == task.nTaskId )
@@ -30,6 +31,176 @@ bool CSATExecutor::IsTaskExist(SATParameters::STTask &task)
 	return found;
 }
 
+SATParameters::STTask* CSATExecutor::IsTaskProcess()
+{
+	std::list<SATParameters::STTask>::iterator it = m_vtTask.begin();
+	for ( ; it != m_vtTask.end(); it++ )
+	{
+		if ( it->_nExecutionState == 1 )
+		{
+			return &(*it);
+		}
+	}
+
+	return NULL;
+}
+
+SATParameters::STTask* CSATExecutor::GetFreeTask()
+{
+	std::list<SATParameters::STTask>::iterator it = m_vtTask.begin();
+	for ( ; it != m_vtTask.end(); it++ )
+	{
+		if ( it->_nExecutionState == 0 )
+		{
+			return &(*it);
+		}
+	}
+
+	return NULL;
+}
+
+SATParameters::STCase* CSATExecutor::IsCaseScriptProcess(std::vector<SATParameters::STCase> &vtCases)
+{
+	std::vector<SATParameters::STCase>::iterator it = vtCases.begin();
+	for ( ; it != vtCases.end(); it++)
+	{
+		if ( it->_nExecutionState == 1 )
+		{
+			return &(*it);
+		}
+	}
+
+	return NULL;
+}
+
+SATParameters::STCase* CSATExecutor::GetFreeCaseScript(std::vector<SATParameters::STCase> &vtCases)
+{
+	std::vector<SATParameters::STCase>::iterator it = vtCases.begin();
+	for ( ; it != vtCases.end(); it++)
+	{
+		if ( it->_nExecutionState == 0 )
+		{
+			return &(*it);
+		}
+	}
+
+	return NULL;
+}
+
+void CSATExecutor::ExecuteFreeCaseScript(SATParameters::STTask* pTask)
+{
+	SATParameters::STCase* pCase = GetFreeCaseScript(pTask->Job.vtCases);
+	if (pCase)
+	{		
+		if ( !pCase->_pExcutor )
+		{
+			CScriptExecutor *pExcutor = new CScriptExecutor();
+			if ( pExcutor )
+			{
+				pCase->_pExcutor = pExcutor;
+				if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strFileDir + "\\" + pCase->_strFileName + ".txt", "", SUBPROCESS) )
+				{
+					pExcutor->StartScript();
+					// 标记用例执行中;
+					pCase->_nExecutionState = 1;
+					// 标记任务为执行中;
+					pTask->_nExecutionState = 1;
+					// 记录开始时间;
+					pCase->_ulStartTickCount = GetTickCount64();
+				}
+			}	
+		}
+		else
+		{
+			CScriptExecutor *pExcutor = (CScriptExecutor *)pCase->_pExcutor;
+		}
+	}
+}
+
+bool CSATExecutor::Login()
+{
+#ifdef _DEBUG
+	std::string url = "http://10.126.16.60:8580/btc_execute_se/ajaxInteractiveManage!executeLogin.action";
+	// 示例值;
+	m_stLoginReq.strUserName = "superAdmin";
+	m_stLoginReq.strStatus = "0";
+	m_stLoginReq.strDeleteStatus = "";
+	m_stLoginReq.strIP = "10.118.158.175";
+	m_stLoginReq.strStorage = "";
+	m_stLoginReq.strConnectTime = "";
+	m_stLoginReq.strExecuteName = "";
+	m_stLoginReq.strMAC = "40:16:7e:23:10:53";
+	m_stLoginReq.strDisconnectTime = "";
+	m_stLoginReq.strPassword = "123456";
+	m_stLoginReq.strCPU = "";
+
+	if ( ::Login(url, m_stLoginReq, m_stLoginResp) )
+	{
+		m_bLogin = TRUE;
+		return true;
+	}
+
+	return false;
+#else
+
+#endif
+}
+
+void CSATExecutor::Logout()
+{
+
+}
+
+bool CSATExecutor::UpdateDevice()
+{
+#ifdef _DEBUG
+	SATParameters::STDevice stDevice;
+	stDevice.strStatus = "0";
+	stDevice.strDeviceSerial = "192.168.1.119:5555";
+	stDevice.strHardwareVersion = "MS6488";
+	stDevice.strManu = "MStar";
+	stDevice.strDeviceMac = "";
+	stDevice.strLastJobStartTime = "";
+	stDevice.strLastTimeBreak = "";
+	stDevice.strComments = "";
+	stDevice.strCPU = "";
+	stDevice.strSoftwareVersion = "1522659174";
+	stDevice.strPhoneNumber = "";
+	stDevice.strLastJobFinishTime = "";
+	stDevice.strMemory = "";
+	stDevice.strModel = "Generic Linux on tcl_ms6488_cn_64_n";
+	stDevice.strLastJob = "";
+	stDevice.strLastTimeConnected = "2019-12-16 10:16:01";
+	stDevice.strElectric = "";
+
+	SATParameters::STUpdateDeviceReq stUpdateDeviceReq;
+	SATParameters::STUpdateDeviceResp stUpdateDeviceResp;
+	std::string url = "http://10.126.16.60:8580/btc_execute_se/ajaxInteractiveManage!updateDeviceMessage.action";
+
+	stUpdateDeviceReq.strStatus = "0";
+	stUpdateDeviceReq.strUserName = "superAdmin";		
+	stUpdateDeviceReq.strIP = "10.118.158.175";
+	stUpdateDeviceReq.strStorage = "228092536KB";
+	stUpdateDeviceReq.strRunnerName = "SAT-Admin";
+	stUpdateDeviceReq.strMAC = "40:16:7e:23:10:53";
+	stUpdateDeviceReq.strReportType = "1";
+	stUpdateDeviceReq.strStartTime = "2019-12-16 19:15:30";
+	stUpdateDeviceReq.strMemory = "8938544KB";
+	stUpdateDeviceReq.strEndTime = "";
+	stUpdateDeviceReq.strCPU = "24.7%";
+	stUpdateDeviceReq.devicelist.push_back(stDevice);
+	m_vtDevice.push_back(stDevice);
+	if ( !::UpdateDeviceMessage(url, stUpdateDeviceReq, stUpdateDeviceResp) )
+	{
+		return false;
+	}
+	
+	return true;
+#else
+
+#endif
+}
+
 void CSATExecutor::StartWork()
 {
 	m_hEventHearbeat = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -109,7 +280,25 @@ DWORD CSATExecutor::HearbeatThread(LPVOID lpVoid)
 			{
 				if (!that->IsTaskExist(*it))
 				{
+					// 将任务压入队列中;
+					AutoThreadSection ats(&that->m_csTask);
+					// 同时下载任务;
+					std::string host = Global::g_stSATConfig.szCaseServer;
+					std::string url = host + "/ajaxInteractiveManage!getCaseFileListUrl.action";
+					std::vector<SATParameters::STCase>::iterator _case = it->Job.vtCases.begin();
+					for ( ;_case != it->Job.vtCases.end(); _case++)
+					{
+						SATParameters::STScriptUrlResp stScriptUrlResp;
+						if ( DownloadScript(url, _case->strId, Global::g_stSATConfig.szScriptDir, stScriptUrlResp) )
+						{
+							_case->_strFileDir = stScriptUrlResp._strFileDir;
+							_case->_strFileName = stScriptUrlResp._strFileName;
+							_case->_strScriptPath = stScriptUrlResp._strScripFile;
+						}
+					}
+
 					that->m_vtTask.push_back(*it);
+					// 待开发:同时将任务存储到数据库中;
 				}
 			}
 		}
@@ -127,8 +316,84 @@ DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
 
 	do 
 	{
-		std::vector<SATParameters::STTask>::iterator it = that->m_vtTask.begin();
+		SATParameters::STTask *pTask = that->IsTaskProcess();
+		if ( pTask )
+		{// 有任务在执行中;
+			if ( pTask->_bConcurrent )
+			{// 并发;
+
+			}
+			else
+			{// 串行,查询执行中的任务是否超时;
+				SATParameters::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
+				if ( pCase )
+				{
+					CScriptExecutor *pExcutor = (CScriptExecutor*)pCase->_pExcutor;
+					if ( pExcutor )
+					{
+						if ( pExcutor->IsScriptOver() )
+						{
+							pCase->_nExecutionState = 2;
+						}
+						else
+						{
+							// 判断是否超时;
+							if ( GetTickCount64() - pCase->_ulStartTickCount > 1800000 )
+							{
+								// 超时中断;
+								pCase->_nExecutionState = 3;
+							}
+						}
+					}
+				}
+				else
+				{
+					// 没有在执行的用例,开始执行新的用例;
+					that->ExecuteFreeCaseScript(pTask);
+				}
+			}
+		}
+		else
+		{
+			// 获取未执行的任务;
+			pTask = that->GetFreeTask();
+			if ( pTask)
+			{
+				// 是否支持并发;
+				if ( pTask->_bConcurrent )
+				{
+					// 暂时全部一起并发;
+					std::vector<SATParameters::STCase>::iterator _case = pTask->Job.vtCases.begin();
+					for ( ; _case != pTask->Job.vtCases.end(); _case++)
+					{
+						if (!_case->_pExcutor)
+						{					
+							CScriptExecutor *pExcutor = new CScriptExecutor();
+							if ( pExcutor )
+							{
+								_case->_pExcutor = pExcutor;
+								pExcutor->InitScript(_case->_strScriptPath, _case->_strFileDir + "\\" + _case->_strFileName + ".txt", "", SUBPROCESS);
+								pExcutor->StartScript();
+								// 标记用例执行中;
+								_case->_nExecutionState = 1;
+							}
+						}
+					}
 
+					// 标记任务为执行中;
+					pTask->_nExecutionState = 1;
+				}
+				else
+				{
+					// 是否有用例脚本在执行;
+					SATParameters::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
+					if ( !pCase )
+					{
+						that->ExecuteFreeCaseScript(pTask);
+					}				
+				}				
+			}		
+		}
 	} while ( WaitForSingleObject(that->m_hEventExcuteScript, 10000) == WAIT_TIMEOUT );
 
 	return 0;

+ 25 - 2
SATService/SATService/SATExecutor.h

@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include "CritSection.h"
+
 class CSATExecutor
 {
 	CSATExecutor(void);
@@ -34,13 +36,32 @@ protected:
 	// 是否登录成功;
 	BOOL	m_bLogin;
 
-	std::vector<SATParameters::STTask> m_vtTask;
+	ThreadSection	m_csTask;
+	std::list<SATParameters::STTask> m_vtTask;
 	std::vector<SATParameters::STDevice> m_vtDevice;
 	SATParameters::STLoginReq	m_stLoginReq;
 	SATParameters::STLoginResp	m_stLoginResp;
 
-
+	// 任务是否存在;
 	bool IsTaskExist(SATParameters::STTask &task);
+	// 是否有任务在执行;
+	SATParameters::STTask* IsTaskProcess();
+	// 提取未执行的任务;
+	SATParameters::STTask* GetFreeTask();
+	// 是否有用例脚本在执行;
+	SATParameters::STCase* IsCaseScriptProcess(std::vector<SATParameters::STCase> &vtCases);
+	// 提取未执行的用例;
+	SATParameters::STCase* GetFreeCaseScript(std::vector<SATParameters::STCase> &vtCases);
+
+	// 执行空闲新用例;
+	void ExecuteFreeCaseScript(SATParameters::STTask* pTask);
+public:
+	// 登录;
+	bool Login();
+	// 登出;
+	void Logout();
+	// 更新设备信息;
+	bool UpdateDevice();
 
 	// 其他接口;
 public:
@@ -49,6 +70,8 @@ public:
 	// 工作结束函数;
 	void EndofWork();
 
+	// 从db中加载任务;
+	void LoadTaskInfo();
 	// 心跳线程;
 	static DWORD WINAPI HearbeatThread(LPVOID lpVoid);
 	// 执行线程;

+ 13 - 6
SATService/SATService/SATService.cpp

@@ -4,6 +4,7 @@
 #include "stdafx.h"
 #include "SATService.h"
 #include "MainProcess.h"
+#include "SATExecutor.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -21,10 +22,15 @@ extern int test();
 void CALLBACK WorkStart()
 {
 #ifdef _DEBUG
-	Sleep(8000);
+	Sleep(20000);
 #endif
 	WindowsService::GetDebugPriv();
-	CMainProcess::GetInstance()->StartWork();
+
+#ifdef _DEBUG
+	CSATExecutor::GetInstance()->Login();
+	CSATExecutor::GetInstance()->UpdateDevice();
+#endif
+	CSATExecutor::GetInstance()->StartWork();
 }
 
 // 工作结束回调函数;
@@ -53,11 +59,12 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	else
 	{
 		// TODO: 在此处为应用程序的行为编写代码。
-#ifdef _DEBUG
-		return test();
-#endif
 		Global::GetIniInfo();
-
+#if 0
+		WorkStart();
+		system("pause");
+		return 0;
+#endif
 		// 进程存在,直接退出;
 		TCHAR szExeName[MAX_PATH] = {0};
 		TCHAR szDrive[_MAX_DRIVE] = { 0 };

+ 366 - 6
SATService/SATService/ScriptExecutor.cpp

@@ -4,6 +4,19 @@
 #include <io.h>
 #include <fcntl.h>
 #include "Python.h"
+// 服务进程头文件;
+#include <Wtsapi32.h>
+#include <TlHelp32.h>
+#pragma comment(lib, "wtsapi32.lib")
+#include <Userenv.h>
+#pragma comment(lib,"userenv.lib")
+
+/*
+typedef struct _TOKEN_LINKED_TOKEN {
+	HANDLE LinkedToken;
+} TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN;
+SERVICE_STATUS_HANDLE hServiceStatus;
+*/
 
 CScriptExecutor::CScriptExecutor(void)
 {
@@ -54,7 +67,8 @@ DWORD CScriptExecutor::_WorkerThread(LPVOID lpParam)
 	}
 	else if (that->m_nRunType == SUBPROCESS)
 	{
-		that->RunScripProcess();
+		//that->RunScriptProcess();
+		that->ServiceRunScriptProcess();
 	}
 
 	CloseHandle(that->m_hWorkThread);
@@ -385,7 +399,7 @@ int CScriptExecutor::RunEmbeddedScript()
 	return 0;
 }
 
-int CScriptExecutor::RunScripProcess()
+int CScriptExecutor::RunScriptProcess()
 {
 	if (!PathFileExists(m_szScriptPath))
 	{
@@ -450,6 +464,168 @@ int CScriptExecutor::RunScripProcess()
 	return 0;
 }
 
+int CScriptExecutor::ServiceRunScriptProcess()
+{
+	if (!PathFileExists(m_szScriptPath))
+	{
+		printf("Error:脚本路径无效\n");
+		return -1;
+	}
+
+	DWORD dwProcesses = 0;
+	BOOL bResult = FALSE;
+	DWORD dwRet = 0;
+	DWORD dwSid = GetActiveSessionID();
+	
+	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);
+
+		// explorer进程不存在
+		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 -1;
+
+	TOKEN_LINKED_TOKEN admin;
+	bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
+
+	if (!bResult) // vista 以前版本不支持TokenLinkedToken
+	{
+		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;
+	}
+
+	LPVOID pEnv =NULL;
+	DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
+
+	if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
+	{
+		dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
+	}
+	else
+	{
+		pEnv = NULL;
+	}
+
+	ZeroMemory( &m_si, sizeof(m_si) );
+	m_si.cb = sizeof(m_si);
+	m_si.dwFlags = STARTF_USESHOWWINDOW;
+	m_si.wShowWindow = SW_HIDE;
+	ZeroMemory( &m_pi, sizeof(m_pi) );
+
+	// 重定向输出;
+	RedirectSubprocessStdout(&m_si);
+	// 恢复日志线程;
+	ResumeThread(m_hLogThread);
+
+	// 强制stdion, stdout和stderr完全无缓冲:python -u
+	TCHAR szCommandLine[MAX_PATH] = { 0 };
+	if (_tcslen(m_szExtraSentence))
+		_stprintf_s(szCommandLine, _T("python -W ignore -u %s %s"), m_szScriptPath, m_szExtraSentence);
+	else
+		_stprintf_s(szCommandLine, _T("python -W ignore -u %s"), m_szScriptPath);
+
+	bResult = CreateProcessAsUser(
+		hUserTokenDup,                     // client's access token
+		NULL,    // file to execute
+		szCommandLine,                 // command line
+		NULL,            // pointer to process SECURITY_ATTRIBUTES
+		NULL,               // pointer to thread SECURITY_ATTRIBUTES
+		TRUE,              // handles are not inheritable
+		dwCreationFlags,     // creation flags
+		pEnv,               // pointer to new environment block
+		NULL,               // name of current directory
+		&m_si,               // pointer to STARTUPINFO structure
+		&m_pi                // receives information about new process
+		);	
+	if ( !bResult )
+		return -1;
+
+	m_bRuned = TRUE;
+	m_dwSubprocessId = m_pi.dwProcessId;
+
+	// 等待进程完成退出.
+	WaitForSingleObject(m_pi.hProcess, INFINITE);
+
+	Sleep(5000);
+	// 结束日志线程;
+	m_bStopLogExport = TRUE;
+
+	// 关闭进程句柄. 
+	CloseHandle(m_pi.hProcess);
+	CloseHandle(m_pi.hThread);
+
+	// 重置;
+	memset(&m_si, 0, sizeof(m_si));
+	memset(&m_pi, 0, sizeof(m_pi));
+	m_si.cb = sizeof(m_si);
+
+	if (hUserTokenDup != NULL)
+		CloseHandle(hUserTokenDup);
+	if (hProcess != NULL)
+		CloseHandle(hProcess);
+	if (hPToken != NULL)
+		CloseHandle(hPToken);
+	if (pEnv != NULL)
+		DestroyEnvironmentBlock(pEnv);
+
+	return TRUE;
+}
+
 bool CScriptExecutor::StartWorkThread()
 {
 	// 创建线程;
@@ -620,13 +796,195 @@ void CScriptExecutor::EndSubprocessStdOut()
 	m_hStdOutRead = NULL;	
 }
 
-void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
+DWORD CScriptExecutor::GetActiveSessionID()
+{
+	DWORD dwSessionId = 0;
+	PWTS_SESSION_INFO pSessionInfo = NULL;
+	DWORD dwCount = 0;
+
+	WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
+
+	for(DWORD i = 0; i < dwCount; i++)
+	{
+		WTS_SESSION_INFO si = pSessionInfo[i];
+		if(WTSActive == si.State)
+		{
+			dwSessionId = si.SessionId;
+			break;
+		}
+	}
+
+	WTSFreeMemory(pSessionInfo);
+
+	return dwSessionId;
+}
+
+BOOL CScriptExecutor::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))
+	{
+		ofile<<"get token error 1"<<std::endl;
+		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);
+
+		// explorer进程不存在
+		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) // vista 以前版本不支持TokenLinkedToken
+	{
+		ofile<<"Get token info error" <<std::endl;
+		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,                     // client's access token
+		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
+		);	
+
+	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 CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
 {
 	// 判断脚本是否存在;
 	if (!PathFileExists(strScript.c_str()))
 	{
 		printf("Error:脚本文件不存在\n");
-		return;
+		return false;
 	}
 
 	// 判断日志文件路径是否可创建;
@@ -636,7 +994,7 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
 		if (!Global::MKDIR(strLogPath.c_str()))
 		{
 			printf("Error:创建目录失败\n");
-			return;
+			return false;
 		}
 
 		// 创建文件;
@@ -644,7 +1002,7 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
 		if ( flog.bad() )
 		{
 			printf("Error:创建文件失败\n");
-			return;
+			return false;
 		}
 		flog.close();
 	}
@@ -656,6 +1014,8 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
 	_tcscpy_s(m_szScriptPath, strScript.c_str());
 	_tcscpy_s(m_szLogPath, strLogPath.c_str());
 	_tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
+
+	return true;
 }
 
 bool CScriptExecutor::StartScript()

+ 7 - 2
SATService/SATService/ScriptExecutor.h

@@ -62,7 +62,8 @@ protected:
 	// 运行嵌入的脚本;
 	int RunEmbeddedScript();
 	// 运行脚本进程;
-	int RunScripProcess();
+	int RunScriptProcess();
+	int ServiceRunScriptProcess();
 	// 开启线程;
 	bool StartWorkThread();
 	bool StartLogThread();
@@ -77,9 +78,13 @@ protected:
 	// 结束重定向句柄,恢复默认;
 	void EndProcessStdOut();
 	void EndSubprocessStdOut();
+	// 获取当前活动的会话ID;
+	DWORD GetActiveSessionID();
+	// 在服务进程下创建子进程;
+	BOOL ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitResult);
 public:
 	// 初始脚本运行参数;
-	void InitScript(
+	bool InitScript(
 		std::string strScript, 
 		std::string strLogPath, 
 		std::string strScriptCmd, 

+ 1 - 1
SATService/SATService/WindowService.cpp

@@ -51,7 +51,7 @@ namespace WindowsService
 	void InitSvcVar()
 	{
 		g_SvcStatusHandle = NULL;
-		g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; // | SERVICE_INTERACTIVE_PROCESSÓë×ŔĂ潝ťĽ;
+		g_SvcStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS; // | SERVICE_INTERACTIVE_PROCESSÓë×ŔĂ潝ťĽ;
 		g_SvcStatus.dwCurrentState = SERVICE_STOPPED;
 		g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
 		g_SvcStatus.dwWin32ExitCode = 0;

+ 1 - 0
SATService/SATService/stdafx.h

@@ -28,6 +28,7 @@
 #include <iostream>
 #include <string>
 #include <vector>
+#include <list>
 #include <Shlwapi.h>
 #include "SATHTTP.h"
 #include "RunPython.h"

+ 3 - 3
SATService/SATService/test.cpp

@@ -56,7 +56,7 @@ __if_not_exists(ProcessJob)
 int test()
 {
 	//std::string host = "http://10.118.158.52:8580";//"http://10.118.158.198:8090";
-	std::string host = "http://10.118.158.198:8090";
+	std::string host = "http://10.126.16.60:8580";
 	SATParameters::STDevice stDevice;
 	stDevice.strStatus = "0";
 	stDevice.strDeviceSerial = "192.168.1.119:5555";
@@ -312,8 +312,8 @@ int test()
 					{
 						if ( DownloadScript(url, it->strId, "D:\\SAT\\", stScriptUrlResp) )
 						{
-							printf("获取脚本下载地址成功:%s\n路径:%s\n", stScriptUrlResp.strURL.c_str(), stScriptUrlResp.strScripFile.c_str());
-							DWORD dwScriptId = RunPyScript(stScriptUrlResp.strScripFile.c_str(), "", "D:\\SAT\\log.txt", TRUE);
+							printf("获取脚本下载地址成功:%s\n路径:%s\n", stScriptUrlResp.strURL.c_str(), stScriptUrlResp._strScripFile.c_str());
+							DWORD dwScriptId = RunPyScript(stScriptUrlResp._strScripFile.c_str(), "", "D:\\SAT\\log.txt", TRUE);
 							if ( dwScriptId != -1 )
 							{
 								ULONGLONG ulTickCount = GetTickCount64();