我正在尝试从服务启动另一个进程(它是一个收集一些数据并将其写入注册表的控制台应用程序)但由于某种原因我无法正常启动它。
我正在尝试做的基础知识如下:
我目前正在使用以下代码:
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcess(PATH, ARGS, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
::WaitForSingleObject(processInfo.hProcess, INFINITE);
DWORD exit = 100;
GetExitCodeProcess(processInfo.hProcess, &exit);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return exit;
}
调用CreateProcess()后,它会成功并进入if语句的主体。对WaitForSingleObject的调用立即返回,它不应该返回,因为该过程大约需要20-30秒才能完成。最后,调用GetExitCodeProcess()失败,并且不设置值“exit”。
仅供参考,这是我在别处成功使用的代码,而不是在服务中。
它是否正在从服务启动并且存在权限问题?
编辑:我现在意识到它实际上会启动应用程序(我可以在TaskMan中看到它),但似乎卡住了。它在那里,但没有做任何事情。
基于Rob Kennedy的suggestion,我修复了流程处理问题,它确实等待流程完成。但除非我手动杀死它,否则它永远不会完成。
答案 0 :(得分:2)
WaitForSingleObject
和GetExitCodeProcess
期望进程处理自身,而不是指向进程句柄的指针。取下&符号。
此外,检查返回值并在失败时调用GetLastError
。这将有助于您诊断未来的问题。永远不要认为API函数总能成功。
一旦你正确地调用了这些函数,并且新进程开始但没有取得进展,你可以合理地确定这个代码不是罪魁祸首。问题在于新流程,因此请将调试任务集中在那里,而不是在服务流程中。
答案 1 :(得分:0)
在更新和编辑之后,这听起来像是从服务启动进程时的许多可能问题之一。您的外部流程是否有可能 - 无论如何 - 等待用户交互?我可以想到三个主要的例子,例如一个命令行应用程序,在某些情况下可能需要键盘输入(例如,像“cmd / c del *。*”这样的东西需要用户确认)。如果应用程序需要一个窗口,并且正在显示它但您无法看到它,则其他示例将适用。如果是这种情况,您可能希望在调试时将服务设置为“与桌面交互”,然后能够看到应用程序窗口(或意外的Windows错误消息,例如无法找到DLL或类似的)。
如果这有助于你调试,通常是“a-ha!”时刻来自于认识到诸如环境变量,路径,当前目录等内容可能不是您在服务中所期望的。权限不是此类问题的最常见原因。您能否提供一些有关您尝试启动的外部应用程序的详细信息,或许这有助于您思考这一点。
答案 2 :(得分:0)
由于您正在启动控制台应用程序,因此可能存在尝试初始化控制台的隐藏启动代码。服务未附加到桌面,我确信该服务启动的进程也不会,因此它将无法创建控制台。这可能是它悬挂的地方。
如果可以,请尝试将您的流程更改为完整的Windows可执行文件,但跳过尝试创建窗口的部分。