凌波多媒体网络教室7.9 怎样防止学生强制退出学生端程序NCStu.exe程序,检测NCStu.exe进程退出,就自动启动NCStu.exe ,并把它做成一个服务,学生端程序安装在C:\Program Files (x86)\lingbo\netclass7\NCStu.exe,供参考
极域也可以这样,只是修改一下服务名及极域学生端程序路径
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <cstdlib>
#include <thread>
#include <chrono>
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle;
bool IsProcessRunning(const std::wstring& processName) {
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W pEntry;
pEntry.dwSize = sizeof(pEntry);
BOOL hRes = Process32FirstW(hSnapShot, &pEntry);
while (hRes) {
if (std::wstring(pEntry.szExeFile) == processName) {
CloseHandle(hSnapShot);
return true;
}
hRes = Process32NextW(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
return false;
}
void RestartProcess(const std::wstring& processPath) {
STARTUPINFOW si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcessW(
NULL, // No module name (use command line)
const_cast<LPWSTR>(processPath.c_str()),
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
CREATE_NO_WINDOW, // Create the process without a window
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure
)) {
// Handle error if necessary
return;
}
// Wait until the process exits
WaitForSingleObject(pi.hProcess, INFINITE);
// Close handles
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
void ServiceMain(int argc, char** argv) {
// 使用 Unicode 版本的 RegisterServiceCtrlHandlerW
serviceStatusHandle = RegisterServiceCtrlHandlerW(L"ky", [](DWORD controlCode) {
switch (controlCode) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
serviceStatus.dwCurrentState = SERVICE_STOPPED;
break;
default:
break;
}
SetServiceStatus(serviceStatusHandle, &serviceStatus);
});
if (!serviceStatusHandle) {
return;
}
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = SERVICE_RUNNING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
const std::wstring processName = L"NCStu.exe";
const std::wstring processPath = L"C:\\Program Files (x86)\\lingbo\\netclass7\\NCStu.exe";
while (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
if (!IsProcessRunning(processName)) {
RestartProcess(processPath);
}
std::this_thread::sleep_for(std::chrono::seconds(5));
}
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
int main() {
// 使用 Unicode 版本的 SERVICE_TABLE_ENTRYW
SERVICE_TABLE_ENTRYW serviceTable[] = {
{ (LPWSTR)L"ky", (LPSERVICE_MAIN_FUNCTIONW)ServiceMain },
{ NULL, NULL }
};
// 使用 Unicode 版本的 StartServiceCtrlDispatcherW
if (!StartServiceCtrlDispatcherW(serviceTable)) {
std::cerr << "StartServiceCtrlDispatcher failed: " << GetLastError() << std::endl;
}
return 0;
}