从服务启动流程

时间:2008-11-25 17:49:49

标签: c++ service createprocess

我正在尝试从服务启动另一个进程(它是一个收集一些数据并将其写入注册表的控制台应用程序)但由于某种原因我无法正常启动它。

我正在尝试做的基础知识如下:

  1. 启动流程
  2. 等待该过程完成
  3. 从流程中检索返回代码
  4. 我目前正在使用以下代码:

    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,我修复了流程处理问题,它确实等待流程完成。但除非我手动杀死它,否则它永远不会完成。

3 个答案:

答案 0 :(得分:2)

WaitForSingleObjectGetExitCodeProcess期望进程处理自身,而不是指向进程句柄的指针。取下&符号。

此外,检查返回值并在失败时调用GetLastError。这将有助于您诊断未来的问题。永远不要认为API函数总能成功。

一旦你正确地调用了这些函数,并且新进程开始但没有取得进展,你可以合理地确定这个代码不是罪魁祸首。问题在于新流程,因此请将调试任务集中在那里,而不是在服务流程中。

答案 1 :(得分:0)

在更新和编辑之后,这听起来像是从服务启动进程时的许多可能问题之一。您的外部流程是否有可能 - 无论如何 - 等待用户交互?我可以想到三个主要的例子,例如一个命令行应用程序,在某些情况下可能需要键盘输入(例如,像“cmd / c del *。*”这样的东西需要用户确认)。如果应用程序需要一个窗口,并且正在显示它但您无法看到它,则其他示例将适用。如果是这种情况,您可能希望在调试时将服务设置为“与桌面交互”,然后能够看到应用程序窗口(或意外的Windows错误消息,例如无法找到DLL或类似的)。

如果这有助于你调试,通常是“a-ha!”时刻来自于认识到诸如环境变量,路径,当前目录等内容可能不是您在服务中所期望的。权限不是此类问题的最常见原因。您能否提供一些有关您尝试启动的外部应用程序的详细信息,或许这有助于您思考这一点。

答案 2 :(得分:0)

由于您正在启动控制台应用程序,因此可能存在尝试初始化控制台的隐藏启动代码。服务未附加到桌面,我确信该服务启动的进程也不会,因此它将无法创建控制台。这可能是它悬挂的地方。

如果可以,请尝试将您的流程更改为完整的Windows可执行文件,但跳过尝试创建窗口的部分。