使用发行版配置+ Unicode字符集的C ++中的基本Windows服务示例代码可以在管理控制台中使用sc start cmd完美启动,但是当我更改配置release +多字节时,比sc start cmd失败,出现最常见的服务错误:1053 -该服务未及时响应启动或控制请求。
我不知道此unicode与多字节配置之间的关系是什么。甚至我都对每个函数后缀进行了交叉检查,这在unicode模式后缀中是W而在多字节模式后缀中是A
#define SERVICE_NAME "USB Device Monitor Service"
#define SLEEP_TIME (1000)
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain()
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
Status.dwWin32ExitCode = 0;
Status.dwServiceSpecificExitCode = 0;
Status.dwCheckPoint = 0;
Status.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandlerEx(SERVICE_NAME, (LPHANDLER_FUNCTION_EX)ControlHandler, 0);
if ((SERVICE_STATUS_HANDLE)0 == hStatus)
{
// Error
}
SetServiceStatus(hStatus, &Status);
Status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &Status);
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
// Initialization
hDeviceNotify = RegisterDeviceNotification((HANDLE)hStatus, &NotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE);
if (NULL == hDeviceNotify)
{
// Error
}
while (SERVICE_RUNNING == Status.dwCurrentState)
{
Sleep(SLEEP_TIME);
}
}
DWORD ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lParam, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
CloseHandle(hPipe);
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)
SetServiceStatus(hStatus, &Status);
break;
}
return NO_ERROR;
}
答案 0 :(得分:0)
您的ServiceMain()
和ControlHandler()
函数被声明为错误,但是您正在使用类型转换来阻止编译器发出抱怨。每当您不得不使用类型转换来使编译器安静时,请考虑您的代码正在尝试做什么,因为它可能做错了事。
此外,您传递给StartServiceCtrlDispatcher()
的SERVICE_TABLE_ENTRY[]
数组是不完整的-您不能像文档中所说的那样以NULL终止数组。
为此,您声称您的服务在为Unicode编译时可以工作,但是您显示的代码实际上不会在Unicode下编译,因为ServiceTable[0].lpServiceName
字段将使用Unicode字符串,但显示的代码而是分配一个ANSI字符串,这是一个错误。
我建议您阅读Microsoft的文档,并密切注意它提供的示例:
以下任务由service programs执行:
- Writing a Service Program's main Function
- Writing a ServiceMain Function
- Writing a Control Handler Function
相关主题
话虽如此,请尝试以下类似操作:
#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;
}