zoukankan      html  css  js  c++  java
  • win32 创建服务 (转)

    本文主要介绍了 OpenSCManager、CreateService、OpenService、ControlService、DeleteService、 RegisterServiceCtrlHandler、SetServiceStatus、StartServiceCtrlDispatcher等操 作服务程序的主要几个API的用法,具体的函数参数大家可以查阅MSDN。

    为什么要使用服务应该程序呢?服务程序就像系统的一些服务一样,能够自动地启动,并执行相应的操作;而且因为服务程序的在层次上和一般的应用程序不同,其 能够在系统启动时就自动地运行,而不像一般的应用程序那样一定要在登陆后才能运行,这些就是服务的一些好处了,如果你也想你的程序具有这样的功能,那么你 就可以建立一个服务应用程序了。下面就跟着我一步一步地教你怎么去创建一个服务应用程序吧。

    一、建立 Win32 Application 应用程序(当然你也可以建立其它的应用程序,但服务一般是没有用户界面的),并命名为 ServiceTest。

     

    二、定义全局函数变量。这里主要是设置服务句柄和状态。

    01.BOOL IsInstalled();
    02.BOOL Install();
    03.BOOL Uninstall();
    04.void LogEvent(LPCTSTR pszFormat, ...);
    05.void WINAPI ServiceMain();
    06.void WINAPI ServiceStrl(DWORD dwOpcode);
    07. 
    08.TCHAR szServiceName[] = _T("ServiceTest");
    09.BOOL bInstall;
    10.SERVICE_STATUS_HANDLE hServiceStatus;
    11.SERVICE_STATUS status;
    12.DWORD dwThreadID;

    三、添加Init初始化函数。

    01.void Init()
    02.{
    03.hServiceStatus = NULL;
    04.status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    05.status.dwCurrentState = SERVICE_STOPPED;
    06.tatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    07.status.dwWin32ExitCode = 0;
    08.status.dwServiceSpecificExitCode = 0;
    09.status.dwCheckPoint = 0;
    10.status.dwWaitHint = 0;
    11.}

    四、添加安装和删除服务函数。这里主要是用到了四个函数 OpenSCManager 和 CreateService。OpenSCManager 用于打开服务控制管理器;CreateService 用于创建服务;OpenService用于打开已有的服务,返回该服务的句柄;ControlService则用于控制已打开的服务状态,这里是让服务停 止后才删除;DeleteService 用于删除指定服务。

    01.BOOL Install();
    02.{
    03.//这里列出主要的两个函数,其它的可以在代码里找。
    04. 
    05.//打开服务控制管理器
    06.OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    07. 
    08.//创建服务
    09.SC_HANDLE hService = ::CreateService(
    10.hSCM, szServiceName, szServiceName,
    11.SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
    12.SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
    13.szFilePath, NULL, NULL, _T(""), NULL, NULL);
    14. 
    15.::CloseServiceHandle(hService);
    16.::CloseServiceHandle(hSCM);
    17.}
    18. 
    19. 
    20.BOOL Uninstall();
    21.{
    22.//这里列出主要的两个函数,其它的可以在代码里找。
    23. 
    24.//打开服务控制管理器
    25.OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    26. 
    27.//打开服务
    28.OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
    29. 
    30.//停止服务
    31.ControlService(hService, SERVICE_CONTROL_STOP, &status);
    32. 
    33.//删除服务
    34.DeleteService(hService);
    35. 
    36.
    37.}

    五、添加服务主线程函数和控制函数。这里调用 RegisterServiceCtrlHandler 来注册服务的控制函数,这里要设置status.dwControlsAccepted 为 SERVICE_ACCEPT_STOP,否则你不能控制这个服务的状态。

    01.void WINAPI ServiceMain()
    02.{
    03.// Register the control request handler
    04.status.dwCurrentState = SERVICE_START_PENDING;
    05.status.dwControlsAccepted = SERVICE_ACCEPT_STOP;//这个要使用,否则你不能控制
    06. 
    07.//注册服务控制
    08.hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
    09.if (hServiceStatus == NULL)
    10.{
    11.LogEvent(_T("Handler not installed"));
    12.return;
    13.}
    14.SetServiceStatus(hServiceStatus, &status);
    15. 
    16.status.dwWin32ExitCode = S_OK;
    17.status.dwCheckPoint = 0;
    18.status.dwWaitHint = 0;
    19.status.dwCurrentState = SERVICE_RUNNING;
    20.SetServiceStatus(hServiceStatus, &status);
    21. 
    22.//模拟服务的运行,10后自动退出。应用时将主要任务放于此即可
    23.int i = 0;
    24.while (i < 10)
    25.{
    26.Sleep(1000);
    27.i++;
    28.}
    29.//
    30. 
    31.status.dwCurrentState = SERVICE_STOPPED;
    32.SetServiceStatus(hServiceStatus, &status);
    33.LogEvent(_T("Service stopped"));
    34.}

    六、在主线程函数里注册控制函数和程序执行主体。这里主要是说明这就是程序的执行体。

    01.void WINAPI ServiceMain()
    02.{
    03.
    04. 
    05.//模拟服务的运行,10后自动退出。应用时将主要任务放于此即可
    06.int i = 0;
    07.while (i < 10)
    08.{
    09.Sleep(1000);
    10. 
    11.i++;
    12.}
    13. 
    14.
    15.}

    七、最后,要在main函数里注册添加安装、删除、注册主函数。

    01.int APIENTRY WinMain(HINSTANCE hInstance,
    02.HINSTANCE hPrevInstance,
    03.LPSTR     lpCmdLine,
    04.int       nCmdShow)
    05.{
    06.Init();
    07.dwThreadID = ::GetCurrentThreadId();
    08.SERVICE_TABLE_ENTRY st[] =
    09.{
    10.{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
    11.{ NULL, NULL }
    12.};
    13. 
    14.if (stricmp(lpCmdLine, "/install") == 0)
    15.{
    16.Install();
    17.}
    18.else if (stricmp(lpCmdLine, "/uninstall") == 0)
    19.{
    20.Uninstall();
    21.}
    22.else
    23.{
    24.if (!::StartServiceCtrlDispatcher(st))
    25.{
    26.LogEvent(_T("Register Service Main Function Error!"));
    27.}
    28.}
    29.return 0;
    30.}

    八、总结。其实做一个服务程序并不难,主要是懂得程序的执行体放于哪里?和注册程序的主函数和注册控制函数,如果这两个没有注册的话,你就程序就不知道如 何去控制了。status.dwControlsAccepted = SERVICE_ACCEPT_STOP;这个也重要,如果你没有设置的话,那么服务就不会受你控制了。

  • 相关阅读:
    HDU 5744
    HDU 5815
    POJ 1269
    HDU 5742
    HDU 4609
    fzu 1150 Farmer Bill's Problem
    fzu 1002 HangOver
    fzu 1001 Duplicate Pair
    fzu 1150 Farmer Bill's Problem
    fzu 1182 Argus 优先队列
  • 原文地址:https://www.cnblogs.com/UnGeek/p/2743023.html
Copyright © 2011-2022 走看看