我编写了一个捕获UDP消息的Windows服务,以用户身份创建进程,通过命名管道将消息发送到进程,然后重复。服务在XP中运行良好,但在一次迭代后在Windows 7中意外终止。事件查看器显示在我将消息传递给服务后,出现应用程序错误,然后意外终止了我的服务。应用程序错误说错误模块是ntdll.dll。调试我的服务会显示代码停止的位置。
这是我的工作循环。
do
{
DebugLog("Waiting For UDP message");
if(recvfrom(socketId, buffer, buffSize, 0, &clientAddrCast, &size) >= 0)
{
DebugLog("Create Named Pipe");
hPipe = CreateNamedPipe(lpszPipename, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message pipe
PIPE_READMODE_MESSAGE, // message read mode
1, // maximum Instaces
buffSize, // output buffer size
buffSize, // input buffer size
5000, // client time-out
&pSecAttrib); // security attributes
if (hPipe == INVALID_HANDLE_VALUE)
ErrorLog("CreateNamedPipe");
DebugLog("Create User Process");
if(!CreateProcessAsUser(hTokenDupe, "C:\\Services\\UDPClient_UserApp.exe", NULL, NULL, NULL, false, dwCreationFlags, NULL, NULL, &si, &pi))
{
// if client app fails use SendMessage as failsafe
//WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, sessionID, pTitle, sizeof(pTitle),
//buffer, sizeof(buffer), MB_OK, 30, &resp, false);
ErrorLog("CreateProcess");
}
else
{
DebugLog("Writing to User Process");
// Open pipe to client
if(cSuccess = ConnectNamedPipe(hPipe, NULL) == 0)
ErrorLog("ConnectNamedPipe");
else
{
Sleep(2000);
cbToWrite = (lstrlen(buffer)+1)*sizeof(TCHAR);
if(!WriteFile(
hPipe, // pipe handle
buffer, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL)) // not overlapped
ErrorLog("WriteFile");
}
}
}
DebugLog("Cleanup");
DestroyEnvironmentBlock(&pEnv);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
ErrorLog("test");
}while(gServiceStatus.dwCurrentState == SERVICE_RUNNING);
我在XP中的调试日志显示在DebugLog("Cleanup")
之后它会循环回DebugLog("Waiting For UDP message")
。在Windows 7中,它在DebugLog("Cleanup")
之后停止。我正在研究我的代码可能会产生的问题。任何其他建议将不胜感激。
谢谢, 约瑟夫G。
答案 0 :(得分:0)
我的猜测是Win7的安全性越来越高。
这里缺少代码,例如pSecAttrib
中的内容是什么?加强您的错误处理,以便(例如)如果管道创建失败,您不会执行循环体的其余部分,并且您确切知道哪个API失败以及原因。
CreateProcessAsUser
- 您运行该服务的用户是什么?该用户是否具有正确的权限 - 它们在Win7与WinXP上可能不同。
在所有 Win32失败后记录GetLastError()
值。让自己的生活更轻松,有一天可以在远程站点中进行生产,那么您将如何排除故障呢?
Sleep(2000);
的内容是什么?可疑。如果管道打开,为什么不发送数据并避免这种延迟。命名管道服务器代码是否很慢,以便在管道上发布读取请求?