а кто сказал, что 20 секунд хватит, или что вообще за определенное время служба остановится? все команды системы возвращаются сразу после отправки сервису команд start|stop. И если сервис не успевает выгрузиться и при этом получает команду start, он прекращает перезапуск. Я использовал когда-то таймаут, но это подвело меня в самый неподходящий момент. Именно поэтому я для этих целей дописал программулю, которая посылает команду службе, и дожидается, пока та выполнится. И только после этого я посылаю (в пакетном режиме) команду start. Таким образом я отключаю агент 1С:82, потом скуль (заодно - он тоже отжирает порой память), затем запускаю скуль, и запускаю 1С. Потому, что ждать пока фирма 1с соизволит исправить миллионы ошибок в коде - нет смысла. Особенно убивает, как они, не читая сообщений, отвечают шаблонными сообщениями типа "пришлите скриншоты, ничё не паняна...", а при этом всё сообщение пестрит рисунками на скриншотах как для "самых маленьких". Ща материться начну.. У меня сейчас сервер 8.2 х64 не перезапускает автоматически процессы. Не перезапускает их и при превышении объёма памяти. И я уже устал отправлять логи и картинки. Бестолково это.
// svcctrl.cpp: определяет точку входа для консольного приложения.
//
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <aclapi.h>
#include <stdio.h>
TCHAR szCommand[10];
TCHAR szSvcName[80];
SC_HANDLE schSCManager;
SC_HANDLE schService;
VOID DisplayUsage(TCHAR *);
VOID DoStartSvc(TCHAR *);
VOID DoStopSvc(TCHAR *);
void ErrorReport(PSTR);
BOOL StopDependentServices(void);
void _tmain(int argc, TCHAR *argv[])
{
TCHAR *compName = NULL;
printf("\n");
if( argc < 3 )
{
printf("ERROR: Incorrect number of arguments\n\n");
DisplayUsage(argv[0]);
return;
}
StringCchCopy(szCommand, 10, argv[1]);
StringCchCopy(szSvcName, 80, argv[2]);
if (argc = 4)
{
compName = argv[3];
}
if (lstrcmpi( szCommand, TEXT("start")) == 0 )
DoStartSvc(compName);
else if (lstrcmpi( szCommand, TEXT("stop")) == 0 )
DoStopSvc(compName);
else
{
_tprintf(TEXT("Unknown command (%s)\n\n"), szCommand);
DisplayUsage(argv[0]);
}
}
void ErrorReport(CHAR *lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlenA((LPCSTR)lpMsgBuf)+lstrlenA((LPSTR)lpszFunction)+40)*sizeof(CHAR));
StringCchPrintfA((LPSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(CHAR),
"%s failed with error code %d: %s",
lpszFunction, dw, lpMsgBuf);
CharToOemA((CHAR*)lpDisplayBuf,(CHAR*)lpDisplayBuf);
printf((CHAR*)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
VOID DisplayUsage(TCHAR *pn)
{
printf("Description:\n");
printf("\tCommand-line tool that controls a service.\n\n");
printf("Usage:\n");
printf("\t %S [command] [service_name] {[computer]}\n\n", pn);
printf("\t[command]\n");
printf("\t start\n");
printf("\t stop\n");
}
//
// Purpose:
// Starts the service.
//
// Parameters:
// None
//
// Return value:
// None
//
VOID DoStartSvc(TCHAR *compName)
{
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwBytesNeeded;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
compName, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
//printf("OpenSCManager failed (%d)\n", GetLastError());
ErrorReport("OpenSCManager");
return;
}
// Get a handle to the service
schService = OpenService(
schSCManager, // SCM database
szSvcName, // name of service
SERVICE_ALL_ACCESS); // full access
if (schService == NULL)
{
//printf("OpenService failed (%d)\n", GetLastError());
ErrorReport("OpenService");
CloseServiceHandle(schSCManager);
return;
}
// Attempt to start the service.
if (!StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
//printf("StartService failed (%d)\n", GetLastError());
ErrorReport("StartService");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
else printf("Service start pending...\n");
// Check the status until the service is no longer start pending.
if (!QueryServiceStatusEx(
schService, // 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
{
return;
}
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.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 = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if (!QueryServiceStatusEx(
schService, // 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
break;
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint.
break;
}
}
}
// Determine whether the service is running.
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("Service started successfully.\n");
}
else
{
printf("Service not started. \n");
printf(" Current State: %d\n", ssStatus.dwCurrentState);
printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode);
printf(" Check Point: %d\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %d\n", ssStatus.dwWaitHint);
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
//
// Purpose:
// Stops the service.
//
// Parameters:
// None
//
// Return value:
// None
//
VOID DoStopSvc(TCHAR *compName)
{
SERVICE_STATUS_PROCESS ssp;
DWORD dwStartTime = GetTickCount();
DWORD dwBytesNeeded;
DWORD dwTimeout = 120000; // 2-minutes time-out
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
compName, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
//printf("OpenSCManager failed (%d)\n", GetLastError());
ErrorReport("OpenSCManager");
return;
}
// Get a handle to the service.
schService = OpenService(
schSCManager, // SCM database
szSvcName, // name of service
SERVICE_STOP |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS);
if (schService == NULL)
{
//printf("OpenService failed (%d)\n", GetLastError());
ErrorReport("OpenService");
CloseServiceHandle(schSCManager);
return;
}
// Make sure the service is not already stopped.
if ( !QueryServiceStatusEx(
schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
{
//printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
ErrorReport("QueryServiceStatusEx");
goto stop_cleanup;
}
if ( ssp.dwCurrentState == SERVICE_STOPPED )
{
printf("Service is already stopped.\n");
return;
}
// If a stop is pending, wait for it.
while ( ssp.dwCurrentState == SERVICE_STOP_PENDING )
{
printf("Service stop pending...\n");
Sleep( ssp.dwWaitHint );
if ( !QueryServiceStatusEx(
schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
{
// printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
ErrorReport("QueryServiceStatusEx");
goto stop_cleanup;
}
if ( ssp.dwCurrentState == SERVICE_STOPPED )
{
printf("Service stopped successfully.\n");
goto stop_cleanup;
}
if ( GetTickCount() - dwStartTime > dwTimeout )
{
printf("Service stop timed out.\n");
goto stop_cleanup;
}
}
// If the service is running, dependencies must be stopped first.
StopDependentServices();
// Send a stop code to the service.
if ( !ControlService(
schService,
SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS) &ssp ) )
{
//printf( "ControlService failed (%d)\n", GetLastError() );
ErrorReport("ControlService");
goto stop_cleanup;
}
// Wait for the service to stop.
while ( ssp.dwCurrentState != SERVICE_STOPPED )
{
Sleep( ssp.dwWaitHint );
if ( !QueryServiceStatusEx(
schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
{
//printf( "QueryServiceStatusEx failed (%d)\n", GetLastError() );
ErrorReport("QueryServiceStatusEx");
goto stop_cleanup;
}
if ( ssp.dwCurrentState == SERVICE_STOPPED )
break;
if ( GetTickCount() - dwStartTime > dwTimeout )
{
printf( "Wait timed out\n" );
goto stop_cleanup;
}
}
printf("Service stopped successfully\n");
stop_cleanup:
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
BOOL StopDependentServices()
{
DWORD i;
DWORD dwBytesNeeded;
DWORD dwCount;
LPENUM_SERVICE_STATUS lpDependencies = NULL;
ENUM_SERVICE_STATUS ess;
SC_HANDLE hDepService;
SERVICE_STATUS_PROCESS ssp;
DWORD dwStartTime = GetTickCount();
DWORD dwTimeout = 30000; // 30-second time-out
// Pass a zero-length buffer to get the required buffer size.
if ( EnumDependentServices( schService, SERVICE_ACTIVE,
lpDependencies, 0, &dwBytesNeeded, &dwCount ) )
{
// If the Enum call succeeds, then there are no dependent
// services, so do nothing.
return TRUE;
}
else
{
if ( GetLastError() != ERROR_MORE_DATA )
return FALSE; // Unexpected error
// Allocate a buffer for the dependencies.
lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );
if ( !lpDependencies )
return FALSE;
__try {
// Enumerate the dependencies.
if ( !EnumDependentServices( schService, SERVICE_ACTIVE,
lpDependencies, dwBytesNeeded, &dwBytesNeeded,
&dwCount ) )
return FALSE;
for ( i = 0; i < dwCount; i++ )
{
ess = *(lpDependencies + i);
// Open the service.
hDepService = OpenService( schSCManager,
ess.lpServiceName,
SERVICE_STOP | SERVICE_QUERY_STATUS );
if ( !hDepService )
return FALSE;
__try {
// Send a stop code.
if ( !ControlService( hDepService,
SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS) &ssp ) )
return FALSE;
// Wait for the service to stop.
while ( ssp.dwCurrentState != SERVICE_STOPPED )
{
Sleep( ssp.dwWaitHint );
if ( !QueryServiceStatusEx(
hDepService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
return FALSE;
if ( ssp.dwCurrentState == SERVICE_STOPPED )
break;
if ( GetTickCount() - dwStartTime > dwTimeout )
return FALSE;
}
}
__finally
{
// Always release the service handle.
CloseServiceHandle( hDepService );
}
}
}
__finally
{
// Always free the enumeration buffer.
HeapFree( GetProcessHeap(), 0, lpDependencies );
}
}
return TRUE;
}
Показать