用C++创建Windows服务代码
2015-02-05 17:19
375 查看
Create a new C++ project. I used simply Empty Win32 Console Application in Visual Studio.
Every service has to contain following items :
A Main Entry point (like any application)
A Service Entry point
A Service Control Handler
Before writing Main Entry point we must declare some variables, which will be used in our application, but to correclty do this let's import following header files :
First we need
which will provide information about status of our service for Service Control Manager (SCM) .
We need also
is used to reference our service instance once it is registered with the SCM.
And there some additional variables, about it I will tell later.
In the main entry point you quickly call
the SCM can call your Service Entry point (
the example above). You want to defer any initialization until your Service Entry point, which is defined next.
Here we have following tasks :
Initialize all necessary tasks from App Main Point
Register the service control handler which will handle Service Stop, Pause, Continue, Shutdown, etc control commands. These
are registered via the
of the
as a bit mask.
Set Service Status to
to
Set status to
any errors and on exit. Always set
0 when setting status to
Perform start up tasks. Like creating threads/events/mutex/IPCs/etc.
The Service Control Handler was registered in your Service Main Entry point. Each service must have a handler to handle control requests from the SCM. The control handler must return within 30 seconds or the SCM will return an error stating that the service
is not responding. This is because the handler will be called in the context of the SCM and will hold the SCM until it returns from the handler.
And now we're going to the penultimate step :
This sample Service Worker Thread does nothing but sleep and check to see if the service has received a control to stop. Once a stop control has been received the Service Control Handler sets the
The Service Worker Thread breaks and exits. This signals the Service Main routine to return and effectively stop the service.
Every services have to be installed into the OS. To do that type that command in cmd line :
sc create "The name of service" binPath= C:\OurExecutableFileWithService.exe
If we want use service never more, we should uninstall service from Windows.
sc delete "The name of service"
There is also a possibility to install and uninstall(and also manage) a service directly from application - to do that read about CServiceHelper class.
This tutorial has been written based on :
http://msdn.microsoft.com/en-us/library/bb540476%28v=VS.85%29.aspx
http://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus
http://code.msdn.microsoft.com/windowsdesktop/CppWindowsService-cacf4948
http://msdn.microsoft.com/en-us/library/40xe80wx%28v=vs.90%29.aspx
http://www.asawicki.info/news_1404_coding_windows_services_in_c.html
Coding
Every service has to contain following items :A Main Entry point (like any application)
A Service Entry point
A Service Control Handler
Before writing Main Entry point we must declare some variables, which will be used in our application, but to correclty do this let's import following header files :
#include <windows.h> #include <tchar.h> #include <strsafe.h> #pragma comment(lib, "advapi32.lib")
First we need
SERVICE_STATUSstructure
which will provide information about status of our service for Service Control Manager (SCM) .
SERVICE_STATUS g_ServiceStatus = {0};
We need also
SERVICE_STATUS_HANDLEthat
is used to reference our service instance once it is registered with the SCM.
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
And there some additional variables, about it I will tell later.
HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE; VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv); //service entry point VOID WINAPI ServiceCtrlHandler (DWORD); DWORD WINAPI ServiceWorkerThread (LPVOID lpParam); //service thread #define SERVICE_NAME _T("My Sample Service"); //here we can write the visible name of our service
Application Main Entry point
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; }
In the main entry point you quickly call
StartServiceCtrlDispatcherso
the SCM can call your Service Entry point (
ServiceMainin
the example above). You want to defer any initialization until your Service Entry point, which is defined next.
Service entry point
VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv) { DWORD Status = E_FAIL; // Register our service control handler with the SCM g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler); if (g_StatusHandle == NULL) { goto EXIT; } // Tell the service controller we are starting 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) { OutputDebugString(_T( "My Sample Service: ServiceMain: SetServiceStatus returned error")); } /* * Perform tasks necessary to start the service here */ // Create a service stop event to wait on later g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL); if (g_ServiceStopEvent == NULL) { // Error creating event // Tell service controller we are stopped and exit g_ServiceStatus.dwControlsAccepted = 0; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwWin32ExitCode = GetLastError(); g_ServiceStatus.dwCheckPoint = 1; if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) { OutputDebugString(_T( "My Sample Service: ServiceMain: SetServiceStatus returned error")); } goto EXIT; } // Tell the service controller we are started g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwCheckPoint = 0; if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) { OutputDebugString(_T( "My Sample Service: ServiceMain: SetServiceStatus returned error")); } // Start a thread that will perform the main task of the service HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL); // Wait until our worker thread exits signaling that the service needs to stop WaitForSingleObject (hThread, INFINITE); /* * Perform any cleanup tasks */ CloseHandle (g_ServiceStopEvent); // Tell the service controller we are stopped g_ServiceStatus.dwControlsAccepted = 0; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwCheckPoint = 3; if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) { OutputDebugString(_T( "My Sample Service: ServiceMain: SetServiceStatus returned error")); } EXIT: return; }
Here we have following tasks :
Initialize all necessary tasks from App Main Point
Register the service control handler which will handle Service Stop, Pause, Continue, Shutdown, etc control commands. These
are registered via the
dwControlsAcceptedfield
of the
SERVICE_STATUSstructure
as a bit mask.
Set Service Status to
SERVICE_PENDINGthen
to
SERVICE_RUNNING.
Set status to
SERVICE_STOPPEDon
any errors and on exit. Always set
SERVICE_STATUS.dwControlsAcceptedto
0 when setting status to
SERVICE_STOPPEDor
SERVICE_PENDING.
Perform start up tasks. Like creating threads/events/mutex/IPCs/etc.
Service Controller Handler
VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode) { switch (CtrlCode) { case SERVICE_CONTROL_STOP : if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING) break; /* * Perform tasks necessary to stop the service here */ g_ServiceStatus.dwControlsAccepted = 0; g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwCheckPoint = 4; if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) { OutputDebugString(_T( "My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error")); } // This will signal the worker thread to start shutting down SetEvent (g_ServiceStopEvent); break; default: break; } }
The Service Control Handler was registered in your Service Main Entry point. Each service must have a handler to handle control requests from the SCM. The control handler must return within 30 seconds or the SCM will return an error stating that the service
is not responding. This is because the handler will be called in the context of the SCM and will hold the SCM until it returns from the handler.
And now we're going to the penultimate step :
Service working thread
WORD WINAPI ServiceWorkerThread (LPVOID lpParam) { // Periodically check if the service has been requested to stop while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0) { /* * Perform main service function here */ // Simulate some work by sleeping Sleep(3000); } return ERROR_SUCCESS; }
This sample Service Worker Thread does nothing but sleep and check to see if the service has received a control to stop. Once a stop control has been received the Service Control Handler sets the
g_ServiceStopEventevent.
The Service Worker Thread breaks and exits. This signals the Service Main routine to return and effectively stop the service.
Installing and uninstalling the service
Installing the service
Every services have to be installed into the OS. To do that type that command in cmd line :sc create "The name of service" binPath= C:\OurExecutableFileWithService.exe
Uninstalling the service
If we want use service never more, we should uninstall service from Windows.sc delete "The name of service"
Other possibilities
There is also a possibility to install and uninstall(and also manage) a service directly from application - to do that read about CServiceHelper class.This tutorial has been written based on :
http://msdn.microsoft.com/en-us/library/bb540476%28v=VS.85%29.aspx
http://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus
http://code.msdn.microsoft.com/windowsdesktop/CppWindowsService-cacf4948
http://msdn.microsoft.com/en-us/library/40xe80wx%28v=vs.90%29.aspx
http://www.asawicki.info/news_1404_coding_windows_services_in_c.html
相关文章推荐
- C++ 创建windows 服务
- C# 自动运行代码 (创建windows 服务的形式 )
- C/C++创建windows服务程序
- 用C/C++创建windows服务程序
- c++写修改Windows服务类型的代码
- C/C++ 创建windows系统服务程序
- 用C/C++创建windows服务程序
- C#创建windows服务搭配定时器Timer使用实例(用代码做,截图版)
- C#创建windows服务搭配定时器Timer使用实例(用代码做,截图版)(从iteye搬到博客园)
- C# 自动运行代码 (创建windows 服务的形式 )
- Windows服务用C++代码实现的一些操作-1:修改服务启动类型
- 用C#创建Windows(NT)服务
- 王晓东原创:C# 简易IDE开发工具-快速创建Windows和Web程序及Web Service服务!
- Delphi 下操作Windows 服务的代码
- 用Visual C#创建Windows服务程序
- 用 C++ 创建简单的 Win32 服务程序
- 用C#创建Windows(NT)服务
- 创建 Windows 服务应用程序
- Windows服务创建及安装
- 用.NET创建Windows服务