📄 win32serviceimpl.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@goertz.com)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#ifndef _WIN32#define _WIN32#endif#include <windows.h>#include <more/os/file.hpp>#include "win32serviceimpl.hpp"using namespace more;using namespace more::os;using namespace more::os::win32;using namespace more::util;////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::Win32ServiceImpl( const String& sName) throw( Win32Service::NotSupported ) : m_sName( sName ){ ServiceManagerGuard serviceManagerGuard;}////////////////////////////////////////////////////////////////////////////////bool Win32ServiceImpl::exists( ) const{ bool bResult = false; ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService = OpenService( serviceManagerGuard, m_sName, SERVICE_ALL_ACCESS ); if( hService != NULL ) { bResult = true; CloseServiceHandle( hService ); } return bResult;}////////////////////////////////////////////////////////////////////////////////String Win32ServiceImpl::getName( ) const{ return m_sName;}////////////////////////////////////////////////////////////////////////////////void Win32ServiceImpl::execute( const p<Win32Service::Servant>& pServant) throw( Win32Service::Unknown ){ if( !exists( ) ) { throw UnknownImpl( m_sName ); } if( pServant != 0 ) { CREATE ServiceCtrlHandler( m_sName, pServant ); }}////////////////////////////////////////////////////////////////////////////////bool Win32ServiceImpl::install( const Array<String>& sArgV, const String& sUser, const String& sPassword) throw( Win32Service::AlreadyExists ){ bool bResult = false; if( exists( ) ) { throw AlreadyExistsImpl( m_sName ); } if( sArgV.getLength( ) > 0 ) { ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService; p<File> pBinary = File::create( sArgV[0] ); String sArgs = pBinary -> getDescriptor( ) -> getFullName( ); const char* pcUser = NULL; const char* pcPassword = NULL; for( size_t i = 1; i < sArgV.getLength( ); i++ ) { sArgs << " \"" << sArgV[i] << "\""; } if( sUser != "" && sPassword != "" ) { pcUser = sUser; pcPassword = sPassword; } hService = CreateService( serviceManagerGuard, // SCManager database m_sName, // name of service m_sName, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type sArgs, // service's binary and args NULL, // no load ordering group NULL, // no tag identifier "", // dependencies pcUser, // user (or NULL) pcPassword ); // password (or NULL) if( hService != NULL ) { CloseServiceHandle( hService ); bResult = true; } } return bResult;}////////////////////////////////////////////////////////////////////////////////bool Win32ServiceImpl::uninstall( ) throw( Win32Service::Unknown ){ bool bResult = false; ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService; hService = OpenService( serviceManagerGuard, m_sName, SERVICE_ALL_ACCESS ); if( hService == NULL ) { throw UnknownImpl( m_sName ); } stop( ); if( DeleteService( hService ) ) { bResult = true; } CloseServiceHandle( hService ); return bResult;}////////////////////////////////////////////////////////////////////////////////void Win32ServiceImpl::start( ) throw( Win32Service::Unknown ){ ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService; hService = OpenService( serviceManagerGuard, m_sName, SERVICE_ALL_ACCESS ); if( hService == NULL ) { throw UnknownImpl( m_sName ); } StartService( hService, 0, NULL ); CloseServiceHandle( hService );}////////////////////////////////////////////////////////////////////////////////void Win32ServiceImpl::stop( ) throw( Win32Service::Unknown ){ ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService; SERVICE_STATUS status; hService = OpenService( serviceManagerGuard, m_sName, SERVICE_ALL_ACCESS ); if( hService == NULL ) { throw UnknownImpl( m_sName ); } ControlService( hService, SERVICE_CONTROL_STOP, &status ); CloseServiceHandle( hService );}////////////////////////////////////////////////////////////////////////////////Win32Service::State Win32ServiceImpl::getState( ) throw( Win32Service::Unknown ){ Win32Service::State eResult = WIN32_SERVICE_STATE_UNKNOWN; ServiceManagerGuard serviceManagerGuard; SC_HANDLE hService; SERVICE_STATUS status; hService = OpenService( serviceManagerGuard, m_sName, SERVICE_ALL_ACCESS ); if( hService == NULL ) { throw UnknownImpl( m_sName ); } QueryServiceStatus( hService, &status ); switch( status.dwCurrentState ) { case SERVICE_STOPPED: eResult = WIN32_SERVICE_STOPPED; break; case SERVICE_START_PENDING: eResult = WIN32_SERVICE_START_PENDING; break; case SERVICE_STOP_PENDING: eResult = WIN32_SERVICE_STOP_PENDING; break; case SERVICE_RUNNING: eResult = WIN32_SERVICE_RUNNING; break; case SERVICE_CONTINUE_PENDING: eResult = WIN32_SERVICE_CONTINUE_PENDING; break; case SERVICE_PAUSE_PENDING: eResult = WIN32_SERVICE_PAUSE_PENDING; break; case SERVICE_PAUSED: eResult = WIN32_SERVICE_PAUSED; break; default: break; } CloseServiceHandle( hService ); return eResult;}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::UnknownImpl::UnknownImpl( const String& sName): m_sDescription( "Service \"" + sName + "\" is unknown" ){}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::UnknownImpl::operator const char* ( ) const{ return m_sDescription;}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::AlreadyExistsImpl::AlreadyExistsImpl( const String& sName): m_sDescription( "Service \"" + sName + "\" already exists" ){}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::AlreadyExistsImpl::operator const char* ( ) const{ return m_sDescription;}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::ServiceManagerGuard::ServiceManagerGuard( ) throw( Win32Service::NotSupported ){ class NotSupportedImpl: public Win32Service::NotSupported { public: virtual operator const char* ( ) const { return "Services not supported on this Win32 platform"; } }; m_hServiceManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( m_hServiceManager == NULL ) { throw NotSupportedImpl( ); }}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::ServiceManagerGuard::~ServiceManagerGuard( ){ CloseServiceHandle( m_hServiceManager );}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::ServiceManagerGuard::operator SC_HANDLE ( ) const{ return m_hServiceManager;}////////////////////////////////////////////////////////////////////////////////Win32ServiceImpl::ServiceCtrlHandler::ServiceCtrlHandler( const String& sName, const p<Win32Service::Servant>& pServant) throw( Win32Service::Unknown ): m_sName( sName ), m_pServant( pServant ), m_nCheckPoint( 0 ), m_hStatus( NULL ){ const char* pcName = m_sName; SERVICE_TABLE_ENTRY dispatchTable[] = { { ( char* ) pcName, ( LPSERVICE_MAIN_FUNCTION ) serviceMain }, { NULL, NULL } }; m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; m_status.dwServiceSpecificExitCode = 0; m_status.dwCheckPoint = 0; Singleton<ServiceCtrlHandler>::setInstance( this ); StartServiceCtrlDispatcher( dispatchTable );}////////////////////////////////////////////////////////////////////////////////void WINAPI Win32ServiceImpl::ServiceCtrlHandler::serviceMain( DWORD nArgC, LPTSTR* pcArgS){ p<ServiceCtrlHandler> pServiceCtrlHandler = Singleton<ServiceCtrlHandler>::getInstance( ); if( pServiceCtrlHandler != 0 ) { const char* pcName = pServiceCtrlHandler -> m_sName; pServiceCtrlHandler -> m_hStatus = RegisterServiceCtrlHandler( ( char* ) pcName, serviceCtrlHandler ); if( pServiceCtrlHandler -> m_hStatus != NULL ) { pServiceCtrlHandler -> updateStatus( SERVICE_START_PENDING, 1000 ); try { pServiceCtrlHandler -> updateStatus( SERVICE_RUNNING ); pServiceCtrlHandler -> m_pServant -> run( ); } catch( ... ) { } pServiceCtrlHandler -> updateStatus( SERVICE_STOPPED ); } }}////////////////////////////////////////////////////////////////////////////////void WINAPI Win32ServiceImpl::ServiceCtrlHandler::serviceCtrlHandler( DWORD nControlCode){ p<ServiceCtrlHandler> pServiceCtrlHandler = Singleton<ServiceCtrlHandler>::getInstance( ); if( nControlCode == SERVICE_CONTROL_STOP ) { pServiceCtrlHandler -> updateStatus( SERVICE_STOP_PENDING, 3000 ); try { pServiceCtrlHandler -> m_pServant -> onStop( ); } catch( ... ) { } } else { pServiceCtrlHandler -> updateStatus( pServiceCtrlHandler -> m_status.dwCurrentState ); }}////////////////////////////////////////////////////////////////////////////////void Win32ServiceImpl::ServiceCtrlHandler::updateStatus( DWORD nNewState, DWORD nMilliSecondsToWait){ if( nNewState == SERVICE_START_PENDING || nNewState == SERVICE_STOP_PENDING ) { m_status.dwControlsAccepted = 0; } else { m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; } m_status.dwCurrentState = nNewState; m_status.dwWin32ExitCode = NO_ERROR; m_status.dwWaitHint = nMilliSecondsToWait; if( nNewState == SERVICE_RUNNING || nNewState == SERVICE_STOPPED ) { m_status.dwCheckPoint = 0; } else { m_status.dwCheckPoint = m_nCheckPoint++; } SetServiceStatus( m_hStatus, &m_status );}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -