123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /****************************** Module Header ******************************\
- * Module Name: ServiceInstaller.cpp
- * Project: CppWindowsService
- * Copyright (c) Microsoft Corporation.
- *
- * The file implements functions that install and uninstall the service.
- *
- * This source is subject to the Microsoft Public License.
- * See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
- * All other rights reserved.
- *
- * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
- * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
- \***************************************************************************/
- #pragma region "Includes"
- #include <stdio.h>
- #include <windows.h>
- #include "ServiceInstaller.h"
- #pragma endregion
- //
- // FUNCTION: InstallService
- //
- // PURPOSE: Install the current application as a service to the local
- // service control manager database.
- //
- // PARAMETERS:
- // * pszServiceName - the name of the service to be installed
- // * pszDisplayName - the display name of the service
- // * dwStartType - the service start option. This parameter can be one of
- // the following values: SERVICE_AUTO_START, SERVICE_BOOT_START,
- // SERVICE_DEMAND_START, SERVICE_DISABLED, SERVICE_SYSTEM_START.
- // * pszDependencies - a pointer to a double null-terminated array of null-
- // separated names of services or load ordering groups that the system
- // must start before this service.
- // * pszAccount - the name of the account under which the service runs.
- // * pszPassword - the password to the account name.
- //
- // NOTE: If the function fails to install the service, it prints the error
- // in the standard output stream for users to diagnose the problem.
- //
- std::string InstallService(PSTR pszServiceName,
- PSTR pszDisplayName,
- DWORD dwStartType,
- PSTR pszDependencies,
- PSTR pszAccount,
- PSTR pszPassword)
- {
- std::string ret;
- char szPathTmp[MAX_PATH],szPath[MAX_PATH];
- SC_HANDLE schSCManager = NULL;
- SC_HANDLE schService = NULL;
- if (GetModuleFileName(NULL, szPathTmp, ARRAYSIZE(szPath)) == 0)
- {
- ret = "GetModuleFileName failed, unable to get path to self";
- goto Cleanup;
- }
- // Quote path in case it contains spaces
- _snprintf_s(szPath,sizeof(szPath),"\"%s\"",szPathTmp);
- // Open the local default service control manager database
- schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT |
- SC_MANAGER_CREATE_SERVICE);
- if (schSCManager == NULL)
- {
- ret = "OpenSCManager failed";
- goto Cleanup;
- }
- // Install the service into SCM by calling CreateService
- schService = CreateService(
- schSCManager, // SCManager database
- pszServiceName, // Name of service
- pszDisplayName, // Name to display
- SERVICE_QUERY_STATUS, // Desired access
- SERVICE_WIN32_OWN_PROCESS, // Service type
- dwStartType, // Service start type
- SERVICE_ERROR_NORMAL, // Error control type
- szPath, // Service's binary
- NULL, // No load ordering group
- NULL, // No tag identifier
- pszDependencies, // Dependencies
- pszAccount, // Service running account
- pszPassword // Password of the account
- );
- if (schService == NULL)
- {
- ret = "CreateService failed";
- goto Cleanup;
- }
- Cleanup:
- // Centralized cleanup for all allocated resources.
- if (schSCManager)
- {
- CloseServiceHandle(schSCManager);
- schSCManager = NULL;
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- schService = NULL;
- }
- return ret;
- }
- //
- // FUNCTION: UninstallService
- //
- // PURPOSE: Stop and remove the service from the local service control
- // manager database.
- //
- // PARAMETERS:
- // * pszServiceName - the name of the service to be removed.
- //
- // NOTE: If the function fails to uninstall the service, it prints the
- // error in the standard output stream for users to diagnose the problem.
- //
- std::string UninstallService(PSTR pszServiceName)
- {
- std::string ret;
- SC_HANDLE schSCManager = NULL;
- SC_HANDLE schService = NULL;
- SERVICE_STATUS ssSvcStatus = {};
- // Open the local default service control manager database
- schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (schSCManager == NULL)
- {
- ret = "OpenSCManager failed";
- goto Cleanup;
- }
- // Open the service with delete, stop, and query status permissions
- schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP |
- SERVICE_QUERY_STATUS | DELETE);
- if (schService == NULL)
- {
- ret = "OpenService failed (is service installed?)";
- goto Cleanup;
- }
- // Try to stop the service
- if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
- {
- Sleep(500);
- while (QueryServiceStatus(schService, &ssSvcStatus))
- {
- if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
- {
- Sleep(500);
- }
- else break;
- }
- }
- // Now remove the service by calling DeleteService.
- if (!DeleteService(schService))
- {
- ret = "DeleteService failed (is service running?)";
- goto Cleanup;
- }
- Cleanup:
- // Centralized cleanup for all allocated resources.
- if (schSCManager)
- {
- CloseServiceHandle(schSCManager);
- schSCManager = NULL;
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- schService = NULL;
- }
- return ret;
- }
|