/****************************** 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 #include #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; }