我使用VS6和ATL与CServiceModule来实现自定义Windows服务。如果发生致命错误,服务应自行关闭。由于CServiceModule在所有文件中都可以通过_Module变量获得,我想到这样的事情导致CServiceModule :: Run停止抽取消息并自行关闭
PostThreadMessage(_Module.dwThreadID, WM_QUIT, 0, 0);
这是正确的还是你有更好的主意?
答案 0 :(得分:0)
我相信如果您这样做,那么服务经理会认为您的服务已经崩溃,如果用户将其设置为自动重启,它将会。
在.NET中,您使用ServiceController来通知您的服务要关闭。我希望它在Win32中类似,因为.NET中的大部分内容都只是包装器。对不起,我没有方便关闭服务的C ++代码,但这里是.NET代码。这有望为您提供所需的信息,或者在MSDN中查找文档。
这是来自某些测试套件代码,因此是错误检查的样式;)您需要将此代码放在一个线程中,以便处理关闭消息。
private void stopPLService( bool close )
{
if ( m_serviceController == null )
{
m_serviceController = new ServiceController( "PLService" );
}
WriteLine( "StopPLService" );
if ( m_serviceController != null )
{
try
{
m_serviceController.Stop();
}
catch
{
// Probably just means that it wasn't running or installed, ignore
}
// Wait up to 30 seconds for the service to stop
try
{
m_serviceController.WaitForStatus( ServiceControllerStatus.Stopped, new TimeSpan( 0, 0, 30 ) );
}
catch ( System.ServiceProcess.TimeoutException )
{
Assert.Fail( "Timeout waiting for PLService to stop" );
}
catch
{
// Not installed, we only care in the start
}
if ( close )
{
m_serviceController.Close();
m_serviceController = null;
}
}
}
答案 1 :(得分:0)
您可能希望使用ControlService或ControlServiceEx方法关闭服务。您应该能够从CServiceModule获得所需的句柄。
答案 2 :(得分:0)
对于自我关闭,您将命令发送到Service Manager。试试这个样本:
BOOL StopServiceCmd ( const char * szServiceName )
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
SERVICE_STATUS ssStatus; // current status of the service
BOOL bRet;
int iCont=0;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager )
{
schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS);
if (schService)
{
// try to stop the service
if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
{
Sleep( 1000 );
while( QueryServiceStatus( schService, &ssStatus ) )
{
iCont++;
if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
{
Sleep( 1000 );
if ( iCont > 4 ) break;
}
else
break;
}
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
bRet = TRUE;
else
bRet = FALSE;
}
CloseServiceHandle(schService);
}
else
bRet = FALSE;
CloseServiceHandle(schSCManager);
}
else
bRet = FALSE;
return bRet;
}