Здравствуйте, nesesser, Вы писали:
N>Я не работал с Wix, но в целом ситуаця видится так — выше в ветке был приведен очень полезный пример кода на VBS, который получает собственно процессы-сервисы системы.
N>Нужно код оформить в виде Custom Action.
N>В CA делаете так: првоеряете наличие нужного сервиса. Если есть, то objService.StopService. А далее должно пройти хорошо, по вашим словам.
Работа с сервисами через WMI, насколько я понимаю, далеко не лучшее решение просто потому что WMI должно быть сперва установлено и сконфигурировано отдельно, поправьте, если я ошибаюсь.
Для остановки/запуска сервиса вполне достаточно следующих функций:
DWORD stopService(LPCTSTR lpszServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE hSCM;
SC_HANDLE schSpooler;
SERVICE_STATUS_PROCESS ssStatus;
SERVICE_STATUS ss;
DWORD dwBytesNeeded;
DWORD dwStartTime = GetTickCount();
DWORD dwTimeout = 10000; // was 30000
DWORD dwWaitTime;
__try
{
if ( !(hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT )) )
{
OUTPUT_SYSTEM_ERROR()
dwRet = GetLastError();
__leave;
}
schSpooler = OpenService(hSCM,lpszServiceName,SERVICE_ALL_ACCESS /*SERVICE_STOP | SERVICE_QUERY_STATUS*/);
if(schSpooler == NULL)
{
OUTPUT_SYSTEM_ERROR()
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if(!QueryServiceStatusEx(schSpooler
,SC_STATUS_PROCESS_INFO
,(LPBYTE) &ssStatus
,sizeof(SERVICE_STATUS_PROCESS)
,&dwBytesNeeded))
{
OUTPUT_SYSTEM_ERROR()
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
{
dwRet = SPOOLER_SUCCESS;
__leave;
}
if( !ControlService( schSpooler, SERVICE_CONTROL_STOP, &ss ) )
{
OUTPUT_SYSTEM_ERROR()
dwRet = GetLastError();
__leave;
}
ssStatus.dwCurrentState = ss.dwCurrentState;
ssStatus.dwWaitHint = ss.dwWaitHint;
while ( ssStatus.dwCurrentState != SERVICE_STOPPED )
{
// 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 = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
if ( !QueryServiceStatusEx(
schSpooler,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssStatus,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
{
dwRet = GetLastError();
__leave;
}
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
break;
if ( GetTickCount() - dwStartTime > dwTimeout )
{
dwRet = SPOOLER_ERROR_TIMEOUT;
__leave;
}
}
}
__finally
{
if ( schSpooler )
CloseServiceHandle( schSpooler );
if ( hSCM )
CloseServiceHandle( hSCM );
}
return dwRet;
}
DWORD startService(LPCTSTR lpszServiceName)
{
DWORD dwRet = SPOOLER_SUCCESS;
SC_HANDLE hSCM;
SC_HANDLE schSpooler;
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwWaitTime;
DWORD dwStartTime = GetTickCount();
DWORD dwTimeout = 10000; // was 30000
DWORD dwBytesNeeded;
__try
{
if ( !(hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT )) )
{
OUTPUT_SYSTEM_ERROR()
dwRet = GetLastError();
__leave;
}
schSpooler = OpenService(hSCM,lpszServiceName,SERVICE_ALL_ACCESS);
if(schSpooler == NULL)
{
OUTPUT_SYSTEM_ERROR()
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if (!StartService(schSpooler, 0, NULL) )
{
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if (!QueryServiceStatusEx(
schSpooler, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(LPBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // if buffer too small
{
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
while (ssStatus.dwCurrentState != SERVICE_RUNNING)
{
// 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 = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if (!QueryServiceStatusEx(
schSpooler, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(LPBYTE)&ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // if buffer too small
{
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if(ssStatus.dwCurrentState == SERVICE_STOPPED || ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
if (!StartService(schSpooler, 0, NULL) )
{
dwRet = SPOOLER_NO_SERVICE;
__leave;
}
if ( GetTickCount() - dwStartTime > dwTimeout )
{
// No progress made within the wait hint
break;
}
}
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
dwRet = SPOOLER_SUCCESS;
else
dwRet = SPOOLER_NOT_STARTED;
}
__finally
{
if(schSpooler)
CloseServiceHandle(schSpooler);
if(hSCM)
CloseServiceHandle(hSCM);
}
return dwRet;
}
BOOL checkServiceRunning(LPCTSTR lpszServiceName)
{
return getServiceStatus(lpszServiceName) == SERVICE_RUNNING;
}
DWORD getServiceStatus(LPCTSTR lpszServiceName)
{
DWORD dwRet = 0;
SC_HANDLE hSCM;
SC_HANDLE schService;
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwBytesNeeded;
__try
{
if ( !(hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT )) )
{
__leave;
}
schService = OpenService(hSCM,lpszServiceName,SERVICE_QUERY_STATUS);
if(schService == NULL)
{
__leave;
}
if(!QueryServiceStatusEx(schService
,SC_STATUS_PROCESS_INFO
,(LPBYTE) &ssStatus
,sizeof(SERVICE_STATUS_PROCESS)
,&dwBytesNeeded))
{
__leave;
}
dwRet = ssStatus.dwCurrentState;
}
__finally
{
if ( schService )
CloseServiceHandle( schService );
if ( hSCM )
CloseServiceHandle( hSCM );
}
return dwRet;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>