PDA

View Full Version : روش ثبت، حذف و دستکاری Windows Services



sasan_vm
جمعه 09 فروردین 1387, 17:56 عصر
سلام

برای یک پروژه که از win32 service استفاده میکرد این کدها رو نوشتم کاملا مطابق راهنمای msdn و 100% تست شده، امیدوارم مفید واقع شود:


bool __fastcall IsServiceStarted(const AnsiString& sService)
{
bool Result;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
__try
{
try
{
SERVICE_STATUS SrvStatus;
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
SrvStatus.dwCurrentState = -1;
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ( ServiceManager )
{
ServiceHandle = OpenService(ServiceManager, sService.c_str(), SERVICE_QUERY_STATUS);
if ( ServiceHandle )
{
if ( QueryServiceStatus(ServiceHandle, &SrvStatus) )
{
Result = (SrvStatus.dwCurrentState == SERVICE_RUNNING);
}
CloseServiceHandle(ServiceHandle);
ServiceHandle = NULL;
}
CloseServiceHandle(ServiceManager);
ServiceManager = NULL;
}
}
catch (Exception &e)
{
throw Exception(e.Message);
}
}
__finally
{
if (ServiceHandle)
CloseServiceHandle(ServiceHandle);
if (ServiceManager)
CloseServiceHandle(ServiceManager);
}
return Result;
}
//------------------------------------------------------------------------------
bool __fastcall IsServiceExist(const AnsiString& sService)
{
bool Result;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
__try
{
try
{
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ( ServiceManager )
{
ServiceHandle = OpenService(ServiceManager, sService.c_str(), SERVICE_QUERY_STATUS);
Result = ServiceHandle;
if ( ServiceHandle )
{
CloseServiceHandle(ServiceHandle);
ServiceHandle = NULL;
}
CloseServiceHandle(ServiceManager);
ServiceManager = NULL;
}
}
catch (Exception &e)
{
throw Exception(e.Message);
}
}
__finally
{
if (ServiceHandle)
CloseServiceHandle(ServiceHandle);
if (ServiceManager)
CloseServiceHandle(ServiceManager);
}
return Result;
}
//------------------------------------------------------------------------------
bool __fastcall UnregisterService(const AnsiString& sService)
{
bool Result;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
__try
{
try
{
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
StopService(sService);
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ( ServiceManager )
{
ServiceHandle = OpenService(ServiceManager, sService.c_str(), DELETE);
if ( ServiceHandle )
{
Result = DeleteService(ServiceHandle);
CloseServiceHandle(ServiceHandle);
ServiceHandle = NULL;
}
CloseServiceHandle(ServiceManager);
ServiceManager = NULL;
}
}
catch (Exception &e)
{
// throw Exception(e.Message);
}
}
__finally
{
if (ServiceHandle)
CloseServiceHandle(ServiceHandle);
if (ServiceManager)
CloseServiceHandle(ServiceManager);
}
return Result;
}
//------------------------------------------------------------------------------
bool __fastcall RegisterService(const AnsiString& sPath, const AnsiString& sService, LPCTSTR lpDependencies, bool Start)
{
bool Result;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
__try
{
try
{
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if ( ServiceManager )
{
ServiceHandle = CreateService(
ServiceManager, // SCManager database
sService.c_str(), // name of service
sService.c_str(), // service 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
sPath.c_str(), // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
lpDependencies, // no dependencies null
NULL, // LocalSystem account
NULL); // no password
if ( ServiceHandle )
{

Result = true;
CloseServiceHandle(ServiceHandle);
ServiceHandle = NULL;
}
CloseServiceHandle(ServiceManager);
ServiceManager = NULL;
}
}
catch (Exception &e)
{
throw Exception(e.Message);
}
}
__finally
{
if (ServiceHandle)
CloseServiceHandle(ServiceHandle);
if (ServiceManager)
CloseServiceHandle(ServiceManager);
}
if (Start && Result)
Result = StartService(sService);
return Result;
}
//------------------------------------------------------------------------------
bool __fastcall StartService(const AnsiString& sService)
{
bool Result;
SERVICE_STATUS SrvStatus;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwStatus;
try
{
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ( ServiceManager )
{
ServiceHandle = OpenService(ServiceManager, sService.c_str(), SERVICE_ALL_ACCESS);
if (ServiceHandle)
{
if ( !StartService(
ServiceHandle, // handle to service
0, // number of arguments
NULL) ) // no arguments
throw Exception("Error: starting service.");
if ( !QueryServiceStatus(
ServiceHandle, // handle to service
&SrvStatus) ) // address of status information structure
throw Exception("Error: query service status.");
dwStartTickCount = GetTickCount();
dwOldCheckPoint = SrvStatus.dwCheckPoint;
while ( SrvStatus.dwCurrentState == SERVICE_START_PENDING )
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.
dwWaitTime = SrvStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if ( !QueryServiceStatus(
ServiceHandle, // handle to service
&SrvStatus) ) // address of structure
break;
if ( SrvStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = SrvStatus.dwCheckPoint;
}
else
{
if( GetTickCount() - dwStartTickCount > SrvStatus.dwWaitHint )
{
// No progress made within the wait hint
break;
}
}
}
Result = (SrvStatus.dwCurrentState == SERVICE_RUNNING);
}
}
}
catch (...)
{
}
return Result;
}
//------------------------------------------------------------------------------
bool __fastcall StopService(const AnsiString& sService, bool StopDependencies)
{
bool Result;
SERVICE_STATUS SrvStatus;
SC_HANDLE ServiceManager;
SC_HANDLE ServiceHandle;
DWORD dwTimeout;
DWORD dwStartTime;

__try
{
try
{
ServiceManager = NULL;
ServiceHandle = NULL;
Result = false;
ServiceManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ( ServiceManager )
{
ServiceHandle = OpenService(ServiceManager, sService.c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
if ( ServiceHandle )
{
dwTimeout = 30000;
dwStartTime = GetTickCount();
if ( !QueryServiceStatus( ServiceHandle, &SrvStatus ) )
throw Exception("Error: Query service status.");
Result = ( SrvStatus.dwCurrentState == SERVICE_STOPPED );
if ( !Result ) // try to stop service
{
while ( SrvStatus.dwCurrentState == SERVICE_STOP_PENDING )
{
Sleep( SrvStatus.dwWaitHint );
if ( !QueryServiceStatus( ServiceHandle, &SrvStatus ) )
throw Exception("Error: Query service status.");
if ( SrvStatus.dwCurrentState == SERVICE_STOPPED )
{
Result = true;
break;
}
if ( GetTickCount() - dwStartTime > dwTimeout )
throw Exception("Error: Time out.");
}
// If the service is running, dependencies must be stopped first
if ( !Result && StopDependencies )
{
DWORD i;
DWORD dwBytesNeeded;
DWORD dwCount;
LPENUM_SERVICE_STATUS lpDependencies = NULL;
ENUM_SERVICE_STATUS ess;
SC_HANDLE hDepService;
// Pass a zero-length buffer to get the required buffer size
if ( EnumDependentServices( ServiceHandle, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount ) )
{
// If the Enum call succeeds, then there are no dependent
// services so do nothing
}
else
{
if ( GetLastError() != ERROR_MORE_DATA )
throw Exception("Unexpected error.");
// Allocate a buffer for the dependencies
lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );
if ( !lpDependencies )
throw Exception("Error: Out of memory.");
__try
{
// Enumerate the dependencies
if ( !EnumDependentServices(ServiceHandle, SERVICE_ACTIVE, lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount) )
throw Exception("Error: Enumerate the dependencies.");
for ( i = 0; i < dwCount; i++ )
{
ess = *(lpDependencies + i);
// Open the service
hDepService = OpenService(ServiceManager, ess.lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
if ( !hDepService )
throw Exception("Error: Open dependencies service.");
__try
{
// Send a stop code
if ( !ControlService(hDepService, SERVICE_CONTROL_STOP, &SrvStatus) )
throw Exception("Error: Send a stop code.");
// Wait for the service to stop
while ( SrvStatus.dwCurrentState != SERVICE_STOPPED )
{
Sleep( SrvStatus.dwWaitHint );
if ( !QueryServiceStatus( hDepService, &SrvStatus ) )
throw Exception("Error: Query service status.");
if ( SrvStatus.dwCurrentState == SERVICE_STOPPED )
break;
if ( GetTickCount() - dwStartTime > dwTimeout )
throw Exception("Error: Time out.");
}
}
__finally
{
// Always release the service handle
CloseServiceHandle( hDepService );
}
}
}
__finally
{
// Always free the enumeration buffer
HeapFree( GetProcessHeap(), 0, lpDependencies );
}
}
}
// Send a stop code to the main service
if ( !Result )
{
if ( !ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &SrvStatus ) )
throw Exception("Error: Control service.");
// Wait for the service to stop
while ( SrvStatus.dwCurrentState != SERVICE_STOPPED )
{
Sleep( SrvStatus.dwWaitHint );
if ( !QueryServiceStatus( ServiceHandle, &SrvStatus ) )
throw Exception("Error: Query service status.");
if ( SrvStatus.dwCurrentState == SERVICE_STOPPED )
{
Result = true;
break;
}
if ( GetTickCount() - dwStartTime > dwTimeout )
throw Exception("Error: Time out.");
}
}
}
CloseServiceHandle(ServiceHandle);
ServiceHandle = NULL;
}
CloseServiceHandle(ServiceManager);
ServiceManager = NULL;
}
}
catch (Exception &e)
{
throw Exception(e.Message);
}
}
__finally
{
if (ServiceHandle)
CloseServiceHandle(ServiceHandle);
if (ServiceManager)
CloseServiceHandle(ServiceManager);
}
return Result;
}
//------------------------------------------------------------------------------