c++代码实现Windows后台服务,定时监控多个进程,使用CreateProcessAsUser实现重启打开界面
时间: 2023-08-31 17:37:25 浏览: 215
CreateProcessAsUser 资料
5星 · 资源好评率100%
### 回答1:
以下是一个简单的C++代码示例,用于实现Windows后台服务,定时监控多个进程,并使用CreateProcessAsUser函数重启并打开进程界面:
```c++
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define SERVICE_NAME _T("MyService")
SERVICE_STATUS g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
int _tmain(int argc, TCHAR* argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
return GetLastError();
}
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
DWORD Status = E_FAIL;
g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
if (g_StatusHandle == NULL)
{
return;
}
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
return;
}
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
return;
}
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(g_ServiceStopEvent);
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
return;
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
switch (CtrlCode)
{
case SERVICE_CONTROL_STOP:
if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
SetEvent(g_ServiceStopEvent);
break;
}
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
DWORD dwWaitTime = 60000; // 1 minute
DWORD dwProcessID = 0;
HANDLE hProcess = NULL;
HANDLE hToken = NULL;
HANDLE hDupToken = NULL;
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szCommandLine[MAX_PATH] = { 0 };
while (WaitForSingleObject(g_ServiceStopEvent, dwWaitTime) != WAIT_OBJECT_0)
{
// Monitor multiple processes
if (GetProcessIdByName(_T("process1.exe"), &dwProcessID))
{
// Process found, do nothing
}
else
{
// Process not found, restart it
if (LogonUser(_T("username"), _T("domain"), _T("password"), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken))
{
if (DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID, NULL, SecurityImpersonation, TokenPrimary, &hDupToken))
{
si.lpDesktop = _T("winsta0\\default");
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
_stprintf_s(szCommandLine, _T("\"C:\\Program Files\\process1.exe\""));
if (CreateProcessAsUser(hDupToken, NULL, szCommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
// Error creating process
}
CloseHandle(hDupToken);
}
else
{
// Error duplicating token
}
CloseHandle(hToken);
}
else
{
// Error logging on user
}
}
}
return ERROR_SUCCESS;
}
BOOL GetProcessIdByName(LPCTSTR lpName, DWORD* pProcessID)
{
PROCESSENTRY32 pe32;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return FALSE;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe32))
{
CloseHandle(hSnapshot);
return FALSE;
}
do
{
if (!_tcsicmp(pe32.szExeFile, lpName))
{
*pProcessID = pe32.th32ProcessID;
CloseHandle(hSnapshot);
return TRUE;
}
} while (Process32Next(hSnapshot, &pe32));
CloseHandle(hSnapshot);
return FALSE;
}
```
该代码中的ServiceWorkerThread函数用于定时监控多个进程。如果某个进程未能找到,则使用CreateProcessAsUser函数创建一个新的进程,并打开其界面。GetProcessIdByName函数用于根据进程名称获取其进程ID。该代码仅供参考,需要根据具体需求进行修改。
### 回答2:
要实现Windows后台服务,定时监控多个进程,并使用CreateProcessAsUser函数来重启和打开界面,可以使用以下步骤:
1. 创建一个Windows服务程序的框架,包括服务的启动、停止和运行的功能。
2. 在服务的运行函数中,使用定时器来定时监控多个进程的状态。可以使用EnumProcesses函数获取当前运行的进程列表,然后遍历列表,使用OpenProcess函数打开每个进程,并使用GetExitCodeProcess函数获取进程的退出码,来判断进程是否正在运行。
3. 如果发现某个进程已经退出,则调用CreateProcessAsUser函数来重启该进程并打开界面。在调用CreateProcessAsUser函数时,需要提供要启动的应用程序的路径、命令行参数等信息。
4. 使用CloseHandle函数关闭每个打开的进程句柄,确保资源的释放。
5. 在服务被停止时,释放所有已经打开的句柄并清理资源。
以上步骤的实现可以参考Windows服务编程的相关文档和示例代码,同时需注意服务程序的安全性和权限管理,特别是在使用CreateProcessAsUser函数时,请确保用户有足够的权限来启动对应的进程。
阅读全文