Ваши функции ServiceMain()
и ControlHandler()
объявлены неправильно, но вы используете приведение типов, чтобы компилятор не жаловался.Каждый раз, когда вам приходится прибегать к использованию приведения типов для успокоения компилятора, подумайте о том, что пытается сделать ваш код, поскольку он, вероятно, делает что-то не так.
Кроме того, массив SERVICE_TABLE_ENTRY[]
, который вы используетепереход к StartServiceCtrlDispatcher()
не завершен - вы не завершаете массив массивом, как указано в документации.
В этом отношении вы заявляете, что ваш сервис работает при компиляции дляUnicode, но код, который вы показали, на самом деле не будет компилироваться под Unicode, потому что поле ServiceTable[0].lpServiceName
будет ожидать строку Unicode, но показанный код вместо этого назначает строку ANSI, что является ошибкой.
Я предлагаю вам прочитать документацию Microsoft и обратить пристальное внимание на примеры, которые она дает:
Задачи программы обслуживания
Следующие задачи выполняются сервисные программы :
См. Также
Полный пример обслуживания
С учетом сказанного,попробуйте что-то вроде этого:
#define SERVICE_NAME TEXT("USB Device Monitor Service")
HANDLE hStopEvent = NULL;
SERVICE_STATUS_HANDLE hStatus = NULL;
SERVICE_STATUS Status;
DWORD WINAPI ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lParam, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_INTERROGATE:
return NO_ERROR;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SetEvent(hStopEvent);
return NO_ERROR;
case SERVICE_CONTROL_DEVICEEVENT:
if ((DBT_DEVICEARRIVAL == dwEventType) || (DBT_DEVICEREMOVECOMPLETE == dwEventType))
{
try
{
DEV_BROADCAST_HDR* header = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (DBT_DEVTYP_DEVICEINTERFACE == header->dbch_devicetype)
{
//parse intrested USB device only
}
}
catch (const std::nullptr_t /*ex*/)
{
//"ERROR: Processing WM_DEVICECHANGE failed
}
}
break;
default:
//"ERROR : Unknown dwControl: dwControl)
break;
}
return NO_ERROR;
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
hStatus = RegisterServiceCtrlHandlerEx(SERVICE_NAME, &ControlHandler, 0);
if (!hStatus)
{
// Error
return;
}
ZeroMemory(&Status, sizeof(Status));
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(hStatus, &Status);
// Initialization
hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hStopEvent)
{
// Error
Status.dwCurrentState = SERVICE_STOPPED;
Status.dwWin32ExitCode = GetLastError();
SetServiceStatus(hStatus, &Status);
return;
}
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
HDEVNOTIFY hDeviceNotify = RegisterDeviceNotification((HANDLE)hStatus, &NotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE);
if (!hDeviceNotify)
{
// Error
Status.dwCurrentState = SERVICE_STOPPED;
Status.dwWin32ExitCode = GetLastError();
SetServiceStatus(hStatus, &Status);
return;
}
Status.dwCurrentState = SERVICE_RUNNING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(hStatus, &Status);
WaitForSingleObject(hStopEvent, INFINITE);
Status.dwCurrentState = SERVICE_STOP_PENDING;
Status.dwControlsAccepted = 0;
SetServiceStatus(hStatus, &Status);
UnregisterDeviceNotification(hDeviceNotify);
CloseHandle(hStopEvent);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
}
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = &ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}