Error startservicectrldispatcherw error ragent

StartServiceCtrlDispatcher не может получить доступ к ошибке 1063 Я пишу на c ++ сервисе, но у меня есть ошибка, и я не могу ее исправить. основная функция моего сервиса Где я отлаживаю свою программу с аргументами командной строки (service_path и action) на StartServiceCtrlDispatcher каждый раз, когда возвращается ошибка 1063. Visual Studio запускаю под Администратором. […]

Содержание

  1. StartServiceCtrlDispatcher не может получить доступ к ошибке 1063
  2. Решение
  3. Другие решения
  4. 1C:Enterprise 8.3 Server Agent не стартует автоматом
  5. Функция StartServiceCtrlDispatcher
  6. Параметры
  7. Возвращаемые значения
  8. StartServiceCtrlDispatcherW function (winsvc.h)
  9. Syntax
  10. Parameters
  11. Return value
  12. Remarks
  13. Examples
  14. StartServiceCtrlDispatcherA function (winsvc.h)
  15. Syntax
  16. Parameters
  17. Return value
  18. Remarks
  19. Examples

StartServiceCtrlDispatcher не может получить доступ к ошибке 1063

Я пишу на c ++ сервисе, но у меня есть ошибка, и я не могу ее исправить.

основная функция моего сервиса

Где я отлаживаю свою программу с аргументами командной строки (service_path и action) на StartServiceCtrlDispatcher каждый раз, когда возвращается ошибка 1063. Visual Studio запускаю под Администратором. Где я пишу неправильный код, пожалуйста, помогите.

ОБНОВИТЬ

Решение

Вы можете только позвонить StartServiceCtrlDispatcher когда ваш процесс был запущен диспетчером управления службами, то есть когда он фактически работает как служба. При вызове из любого другого контекста вы получите ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063).

Судя по виду вашего кода, вы должны только звонить StartServiceControlDispatcher если не был передан аргумент командной строки, например, что-то вроде

Есть также некоторые другие проблемы с вашей функцией main (), в частности:

Неправильная подпись; argv [] это char, а не TCHAR

Кастинг argv [0] в TCHAR

Цикл, который вызывает GetLastError без причины, 114 раз

Использование memcmp вместо strcmp

Я не смотрел на ServiceMain ().

Другие решения

это происходит, когда служба установлена ​​поверх Windows 8 или более поздней версии из 64 битов и вызывается методом StartServiceCtrlDispatcher который вызовет основную точку входа. Но метод StartServiceCtrlDispatcher работает с указателем 8 бит.

Итак, решение состоит в том, чтобы использовать функцию StartServiceCtrlDispatcherW который работает с указателями 16 бит, например:

До: он использует указатель на LPTSTR (8 бит), это тип данных, которые нужны SERVICE_TABLE_ENTRY а также StartServiceCtrlDispatcher:

После: он использует указатель на LPWSTR (16 бит), это тип данных, которые нужны SERVICE_TABLE_ENTRYW а также StartServiceCtrlDispatcherW:

Используйте широкую строку (16 бит на символ) и функции StartServiceCtrlDispatcherW и SERVICE_TABLE_ENTRYW Type вместо StartServiceCtrlDispatcher и SERVICE_TABLE_ENTRY.

Источник

1C:Enterprise 8.3 Server Agent не стартует автоматом

Добрый день, коллеги.
Посоветуйте решение в данной проблеме.
После перезагрузки терминального сервера, служба 1C:Enterprise 8.3 Server Agent автоматически не стартует(в свойствах запуск автоматом включен). Запускается только после ручного запуска со второго раза.
Для уч. записи USR1CV82 права
Log on as batch job
Log on as service
— установлены.
На папку 1cv8, в свойствах безопасности папки USR1CV82 стоит разрешение — Modify

Версия платформы 1С:Предприятие 8.3 (8.3.5.1248)

обнаружил там такое предупреждение:
Система Windows обнаружила, что файл реестра используется другими приложениями или службами. Файл будет сейчас выгружен. Приложения или службы, которые используют файл реестра, могут впоследствии работать неправильно.

ПОДРОБНО —
3 user registry handles leaked from RegistryUserS-1-5-21-1848562363-2380802662-1236399446-1002:
Process 2796 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002
Process 2796 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002Control PanelInternational
Process 2796 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002SoftwareMicrosoftWindowsCurrentVersionExplorer

что это может быть?

обновления были установлены, проблема повторилась.
не знаю, где еще можно смотреть

3 user registry handles leaked from RegistryUserS-1-5-21-1848562363-2380802662-1236399446-1002: Process 2816 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002 Process 2816 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002Control PanelInternational Process 2816 (DeviceHarddiskVolume2Program Files (x86)1cv88.3.5.1248binragent.exe) has opened key REGISTRYUSERS-1-5-21-1848562363-2380802662-1236399446-1002SoftwareMicrosoftWindowsCurrentVersionExplorer

данная ошибка, возникает 2 раза в сутки, судя по журналу.

Источник

Функция StartServiceCtrlDispatcher

Функция StartServiceCtrlDispatcher устанавливает связь главного потока процесса службы с диспетчером управления службами, который заставляет поток быть потоком диспетчера управления службой для вызывающего процесса.

Параметры

[in] Указатель на массив структур SERVICE_TABLE_ENTRY, имеющих в своем составе одну запись для каждой службы, которая может выполнить код в вызывающем процесс. Члены структуры последней записи в таблице должны иметь значения значения ПУСТО (NULL), чтобы определять конец таблицы.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение является ненулевым.

Если функция завершается ошибкой, возвращаемое значение — нуль. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError.

Следующие коды ошибки могут быть установлены диспетчером управления службами. Другие могут установиться функциями реестра, которые вызывает диспетчер управления службами.

Код возврата Описание
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT Как правило, эта ошибка указывает, что программа запускается как консольное приложение, а не как служба.

Если программа запускается как консольное приложение для отладки целевого модуля, структура ее также не вызывает специальный для службы код, когда возвращается эта ошибка.

ERROR_INVALID_DATA Указанная координирующая таблица имеет в своем составе записи, которые находятся в неправильном формате. ERROR_SERVICE_ALREADY_RUNNING Процесс уже вызвал StartServiceCtrlDispatcher. Каждый процесс может вызвать StartServiceCtrlDispatcher только один раз.

Windows NT: Это значение не поддерживается.

Когда диспетчер управления службами запускает процесс службы, он ставит его в режим ожидания, чтобы вызвать функцию StartServiceCtrlDispatcher. Главный поток процесса службы должен сделать этот вызов как можно скорее после того, как он запуститься. Если вызов функции StartServiceCtrlDispatcher завершается успешно, она устанавливает связь вызывающего потока с диспетчером управления службами и не возвращает значение до тех пор, пока все запущенные службы в процессе не завершаться. Диспетчер управления службами использует эту связь, чтобы отправлять управление и запускать службы по запросу главного потока процесса службы. Главный поток действует как диспетчер, вызывая соответствующую функцию HandlerEx, чтобы обработать запросы на управление, или создавая новый поток, чтобы выполнить соответствующую функцию ServiceMain, когда новая служба запускается.

Параметр lpServiceTable имеет в своем составе запись для каждой службы, которая может запуститься в вызывающем процесс. Каждая запись задает функцию ServiceMain для этой службы. Для служб SERVICE_WIN32_SHARE_PROCESS , каждая запись должна иметь в своем составе имя службы. Это имя — имя службы, которое определялось функцией CreateService, когда служба была установлена. Для служб SERVICE_WIN32_OWN_PROCESS игнорируется имя службы в записи таблицы.

Если служба запускается в своем собственном процессе, главный поток процесса службы должен немедленно вызвать StartServiceCtrlDispatcher. Все задачи инициализации делаются в функции ServiceMain службы, когда служба запускается.

Если несколько служб совместно используют процесс и нужна какая-то общая инициализация всего процесса, то нужно прежде всего вызывать любую функцию ServiceMain, главный поток которой может сделать эту работу перед вызовом StartServiceCtrlDispatcher, занимая для нее меньше чем 30 секунд. Иначе, должен создаться другой поток, чтобы сделать инициализацию всего процесса, в то время как главный поток вызывает StartServiceCtrlDispatcher, и стать диспетчером управления службой. Любая специальная для службы инициализация должна все же делаться в отдельных главных функциях служб.

Размещение и совместимость StartServiceCtrlDispatcher

Источник

StartServiceCtrlDispatcherW function (winsvc.h)

Connects the main thread of a service process to the service control manager, which causes the thread to be the service control dispatcher thread for the calling process.

Syntax

Parameters

A pointer to an array of SERVICE_TABLE_ENTRY structures containing one entry for each service that can execute in the calling process. The members of the last entry in the table must have NULL values to designate the end of the table.

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

The following error code can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Return code Description
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT This error is returned if the program is being run as a console application rather than as a service.

If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned.

ERROR_INVALID_DATA The specified dispatch table contains entries that are not in the proper format.
ERROR_SERVICE_ALREADY_RUNNING The process has already called StartServiceCtrlDispatcher. Each process can call StartServiceCtrlDispatcher only one time.

When the service control manager starts a service process, it waits for the process to call the StartServiceCtrlDispatcher function. The main thread of a service process should make this call as soon as possible after it starts up (within 30 seconds). If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager and does not return until all running services in the process have entered the SERVICE_STOPPED state. The service control manager uses this connection to send control and service start requests to the main thread of the service process. The main thread acts as a dispatcher by invoking the appropriate HandlerEx function to handle control requests, or by creating a new thread to execute the appropriate ServiceMain function when a new service is started.

The lpServiceTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored.

If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service’s ServiceMain function when the service is started.

If multiple services share a process and some common process-wide initialization needs to be done before any ServiceMain function is called, the main thread can do the work before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, another thread must be created to do the process-wide initialization, while the main thread calls StartServiceCtrlDispatcher and becomes the service control dispatcher. Any service-specific initialization should still be done in the individual service main functions.

Services should not attempt to display a user interface directly. For more information, see Interactive Services.

Examples

The winsvc.h header defines StartServiceCtrlDispatcher as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.

Источник

StartServiceCtrlDispatcherA function (winsvc.h)

Connects the main thread of a service process to the service control manager, which causes the thread to be the service control dispatcher thread for the calling process.

Syntax

Parameters

A pointer to an array of SERVICE_TABLE_ENTRY structures containing one entry for each service that can execute in the calling process. The members of the last entry in the table must have NULL values to designate the end of the table.

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

The following error code can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Return code Description
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT This error is returned if the program is being run as a console application rather than as a service.

If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned.

ERROR_INVALID_DATA The specified dispatch table contains entries that are not in the proper format.
ERROR_SERVICE_ALREADY_RUNNING The process has already called StartServiceCtrlDispatcher. Each process can call StartServiceCtrlDispatcher only one time.

When the service control manager starts a service process, it waits for the process to call the StartServiceCtrlDispatcher function. The main thread of a service process should make this call as soon as possible after it starts up (within 30 seconds). If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager and does not return until all running services in the process have entered the SERVICE_STOPPED state. The service control manager uses this connection to send control and service start requests to the main thread of the service process. The main thread acts as a dispatcher by invoking the appropriate HandlerEx function to handle control requests, or by creating a new thread to execute the appropriate ServiceMain function when a new service is started.

The lpServiceTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored.

If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service’s ServiceMain function when the service is started.

If multiple services share a process and some common process-wide initialization needs to be done before any ServiceMain function is called, the main thread can do the work before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, another thread must be created to do the process-wide initialization, while the main thread calls StartServiceCtrlDispatcher and becomes the service control dispatcher. Any service-specific initialization should still be done in the individual service main functions.

Services should not attempt to display a user interface directly. For more information, see Interactive Services.

Examples

The winsvc.h header defines StartServiceCtrlDispatcher as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.

Источник


Функция StartServiceCtrlDispatcher устанавливает связь главного
потока процесса службы с диспетчером
управления службами, который заставляет поток быть потоком диспетчера управления
службой для вызывающего процесса. 

Синтаксис

BOOL StartServiceCtrlDispatcher(
  const LPSERVICE_TABLE_ENTRY lpServiceTable
);

Параметры

lpServiceTable

[in] Указатель на массив структур
SERVICE_TABLE_ENTRY
, имеющих в своем
составе одну запись для каждой службы, которая может выполнить код в вызывающем
процесс. Члены структуры последней записи в таблице должны иметь значения
значения ПУСТО (NULL), чтобы определять конец таблицы.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение является ненулевым.

Если функция завершается ошибкой, возвращаемое значение — нуль. Чтобы
получить дополнительную информацию об ошибке, вызовите
GetLastError
.

Следующие коды ошибки могут быть установлены диспетчером управления службами.
Другие могут установиться функциями реестра, которые вызывает диспетчер
управления службами.

Код возврата Описание

ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
Как правило, эта ошибка указывает, что программа
запускается как консольное приложение, а не как служба.

Если программа запускается как консольное приложение для отладки целевого модуля, структура
ее также не вызывает специальный для службы код, когда возвращается эта ошибка.


ERROR_INVALID_DATA
Указанная координирующая таблица имеет в своем составе
записи, которые находятся в  неправильном формате.

ERROR_SERVICE_ALREADY_RUNNING
Процесс уже вызвал
StartServiceCtrlDispatcher. Каждый
процесс может вызвать StartServiceCtrlDispatcher только один раз.

Windows NT:  Это значение не поддерживается.

Замечания

Когда диспетчер управления службами запускает процесс службы, он ставит его
в режим ожидания, чтобы вызвать функцию StartServiceCtrlDispatcher. Главный
поток процесса службы должен сделать этот вызов как можно скорее после того, как
он запуститься. Если вызов функции StartServiceCtrlDispatcher завершается успешно, она
устанавливает связь вызывающего потока с диспетчером управления службами и не
возвращает значение до тех пор, пока все запущенные службы в процессе не
завершаться. Диспетчер управления службами использует эту связь, чтобы
отправлять управление и запускать службы по запросу главного потока процесса
службы. Главный поток действует как диспетчер, вызывая соответствующую функцию

HandlerEx
, чтобы обработать запросы на управление, или создавая новый поток,
чтобы выполнить соответствующую функцию ServiceMain, когда новая служба
запускается.

Параметр lpServiceTable имеет в своем составе запись для каждой службы,
которая может запуститься в вызывающем процесс. Каждая запись задает функцию
ServiceMain для этой службы. Для служб SERVICE_WIN32_SHARE_PROCESS, каждая
запись должна иметь в своем составе имя службы. Это имя — имя службы, которое
определялось функцией CreateService, когда служба была установлена. Для служб
SERVICE_WIN32_OWN_PROCESS игнорируется имя службы в записи таблицы.

Если служба запускается в своем собственном процессе, главный поток процесса
службы должен немедленно вызвать StartServiceCtrlDispatcher. Все задачи
инициализации делаются в функции ServiceMain службы, когда служба запускается.

Если несколько служб совместно используют процесс и нужна какая-то общая
инициализация всего процесса, то нужно прежде всего вызывать любую
функцию ServiceMain, главный поток которой может сделать эту работу перед
вызовом StartServiceCtrlDispatcher, занимая для нее меньше чем 30 секунд. Иначе,
должен создаться другой поток, чтобы сделать инициализацию всего процесса, в то
время как главный поток вызывает StartServiceCtrlDispatcher, и стать диспетчером
управления службой. Любая специальная для службы инициализация должна все же
делаться в отдельных главных функциях служб.

Демонстрационный код

Пример смотри в статье Запись функции ServiceMain.

Смотри также

Обзор Службы,
Функции, используемые службами, 
ControlService,
HandlerEx
ServiceMain,
SERVICE_TABLE_ENTRY

















Размещение и
совместимость
StartServiceCtrlDispatcher


К
Windows XP Да 

л
Windows 2000

Professional
Да

и
Windows NT
Workstation
Да

е
Windows Me Нет

н
Windows 98 Нет

т
Windows 95 Нет
 

С
Windows Server 2003 Да

е

Windows 2000 Server
Да

р

Windows NT Server
Да

в
   

е
   

р
   
Используемая библиотека Advapi32.lib

Используемая DLL

advapi32.dll
 Заголовочный
файл
 
— объявлено в Winsvc.h
 —
включено в
Windows.h
 Unicode Реализуется как
StartServiceCtrlDispatcherW (Unicode)
и StartServiceCtrlDispatcherA (ANSI)
 Замечания
по платформе
Не имеется

Hosted by uCoz

Я пишу на c ++ сервисе, но у меня есть ошибка, и я не могу ее исправить.

основная функция моего сервиса

int main (int argc, TCHAR *argv[])
{DWORD f;
for(int i=0;i<113;i++)
f = GetLastError();
servicePath = LPTSTR(argv[0]);
OutputDebugString(_T("My Sample Service: Main: Entry"));
//InstallService();
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
{NULL, NULL}
};
//  StartService();
if(!StartServiceCtrlDispatcher(ServiceTable)) {
f = GetLastError();
//addLogMessage("Error: StartServiceCtrlDispatcher");

} else if( memcmp(argv[argc-1],"install",7)) {
InstallService();
} else if( memcmp(argv[argc-1],"remove",6)) {
RemoveService();
} else if( memcmp(argv[argc-1],"start",5)) {
StartService();
} else if( memcmp(argv[argc-1],"stop",4))  {
// StopService();
}
//  StopService();
OutputDebugString(_TEXT("My Sample Service: Main: Exit"));
return 0;
}

Где я отлаживаю свою программу с аргументами командной строки (service_path и action) на StartServiceCtrlDispatcher каждый раз, когда возвращается ошибка 1063. Visual Studio запускаю под Администратором. Где я пишу неправильный код, пожалуйста, помогите.

ОБНОВИТЬ

VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;

OutputDebugString(_T("My Sample Service: ServiceMain: Entry"));

g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler);

if (g_StatusHandle == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: RegisterServiceCtrlHandler returned error"));
goto EXIT;
}

// Tell the service controller we are starting
ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

/*
* Perform tasks neccesary to start the service here
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Service Start Operations"));

// Create stop event to wait on later.
g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
OutputDebugString(_T("My Sample Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error"));

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
g_ServiceStatus.dwCheckPoint = 1;

if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
}

// Tell the service controller we are started
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

// Start the thread that will perform the main task of the service
HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

OutputDebugString(_T("My Sample Service: ServiceMain: Waiting for Worker Thread to complete"));

// Wait until our worker thread exits effectively signaling that the service needs to stop
WaitForSingleObject (hThread, INFINITE);

OutputDebugString(_T("My Sample Service: ServiceMain: Worker Thread Stop Event signaled"));/*
* Perform any cleanup tasks
*/
OutputDebugString(_T("My Sample Service: ServiceMain: Performing Cleanup Operations"));

CloseHandle (g_ServiceStopEvent);

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 3;

if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

EXIT:
OutputDebugString(_T("My Sample Service: ServiceMain: Exit"));

return;
}

VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Entry"));

switch (CtrlCode)
{
case SERVICE_CONTROL_STOP :

OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SERVICE_CONTROL_STOP Request"));

if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;

/*
* Perform tasks neccesary to stop the service here
*/

g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;

if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
{
OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
}

// This will signal the worker thread to start shutting down
SetEvent (g_ServiceStopEvent);

break;

default:
break;
}

OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Exit"));
}

DWORD WINAPI ServiceWorkerThread (LPVOID lpParam)
{
OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Entry"));

main2();

OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Exit"));

return ERROR_SUCCESS;
}

1

Решение

Вы можете только позвонить StartServiceCtrlDispatcher когда ваш процесс был запущен диспетчером управления службами, то есть когда он фактически работает как служба. При вызове из любого другого контекста вы получите ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063).

Судя по виду вашего кода, вы должны только звонить StartServiceControlDispatcher если не был передан аргумент командной строки, например, что-то вроде

if (argc < 2)
{
if (!StartServiceCtrlDispatcher(ServiceTable))
{
f = GetLastError();
}
}
else if (strcmp(argv[1], "install")
{
InstallService();
}

и так далее.


Есть также некоторые другие проблемы с вашей функцией main (), в частности:

  • Неправильная подпись; argv [] это char, а не TCHAR

  • Кастинг argv [0] в TCHAR

  • Цикл, который вызывает GetLastError без причины, 114 раз

  • Использование memcmp вместо strcmp

Я не смотрел на ServiceMain ().

3

Другие решения

это происходит, когда служба установлена ​​поверх Windows 8 или более поздней версии из 64 битов и вызывается методом StartServiceCtrlDispatcher который вызовет основную точку входа. Но метод StartServiceCtrlDispatcher работает с указателем 8 бит.

Итак, решение состоит в том, чтобы использовать функцию StartServiceCtrlDispatcherW который работает с указателями 16 бит, например:

До: он использует указатель на LPTSTR (8 бит), это тип данных, которые нужны SERVICE_TABLE_ENTRY а также StartServiceCtrlDispatcher:

SERVICE_TABLE_ENTRY DispatchTable[] = {
{ (LPTSTR)srvName.str().c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL,NULL }
};
StartServiceCtrlDispatcher(DispatchTable);

После: он использует указатель на LPWSTR (16 бит), это тип данных, которые нужны SERVICE_TABLE_ENTRYW а также StartServiceCtrlDispatcherW:

SERVICE_TABLE_ENTRYW DispatchTable[] = {
{ (LPWSTR)srvName.str().c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL,NULL }
};
StartServiceCtrlDispatcherW(DispatchTable);

Заключение:

Используйте широкую строку (16 бит на символ) и функции StartServiceCtrlDispatcherW и SERVICE_TABLE_ENTRYW Type вместо StartServiceCtrlDispatcher и SERVICE_TABLE_ENTRY.

3

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error starting workbench administrator
  • Error starting userland proxy
  • Error starting tomcat context exception org springframework beans factory beancreationexception
  • Error 7 ntc2 opened tefal grill
  • Error 6p2 ariston

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии