【问题标题】:Get the PID of the process started by CreateProcess()获取由 CreateProcess() 启动的进程的 PID
【发布时间】:2013-02-07 18:02:56
【问题描述】:

首先让我声明我不是来自C 背景。我是一名 PHP 开发人员。因此,到目前为止,我编写的所有代码都是通过从其他示例中获取点点滴滴,并对它们进行微调以满足我的要求。因此,如果我提出的问题过于基本或明显,请多多包涵。

我从 FFmpeg 开始使用 CreateProcess()

int startFFmpeg()
{
    snprintf(cmd, sizeof(cmd), "D:\\ffpmeg\bin\ffmpeg.exe -i D:\\video.mpg -r 10 D:\\frames");

    PROCESS_INFORMATION pi;
    STARTUPINFO si={sizeof(si)};
    si.cb = sizeof(STARTUPINFO);
    int ff = CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    return ff;
}

我需要做的是获取该进程的PID,然后稍后检查它是否在一段时间后仍在运行。这基本上就是我要找的:

int main()
{
    int ff = startFFmpeg();
    if(ff)
    {
       // great! FFmpeg is generating frames
       // then some time later
       if(<check if ffmpeg is still running, probably by checking the PID in task manager>) // <-- Need this condition
       {
            // if running, continue
       }
       else
       {
           startFFmpeg();
       }
    } 
  return 0;   
}

我做了一些研究,发现PIDPROCESS_INFORMATION 中返回,但我找不到显示如何获取它的示例。

一些元数据

操作系统:Windows 7
语言:C
IDE:开发 C++

【问题讨论】:

  • 进程 ID 在您作为最后一个参数传递给 CreateProcess()PROCESS_INFORMATION 结构中,在您的情况下是 pi 变量,具体来说: pi.dwProcessId
  • 真的吗?否决票?我认为 SO 的目的是学习和分享。并不是我刚来这里并发布了这个问题。我确实先做作业
  • @WhozCraig:在这种情况下确实是更可取的捷径......!
  • 反对者可能想解释一下!?
  • @alk 谢谢。它已经在我的答案中停留了 10 分钟,这也是他真正想要做的事情的答案:看看一个进程是否已经终止。

标签: c windows winapi pid createprocess


【解决方案1】:

从您作为最后一个参数传递给CreateProcess()PROCESS_INFORMATION 结构中提取它,在您的情况下是pi.dwProcessId

但是,要检查它是否仍在运行,您可能只想等待进程句柄。

static HANDLE startFFmpeg()
{
    snprintf(cmd, sizeof(cmd), "D:\\ffpmeg\bin\ffmpeg.exe -i D:\\video.mpg -r 10 D:\\frames");

    PROCESS_INFORMATION pi = {0};
    STARTUPINFO si = {0};
    si.cb = sizeof(STARTUPINFO);
    if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
    {
        CloseHandle(pi.hThread);
        return pi.hProcess;
    }
    return NULL;
}

在您启动 main() 时,您可以执行类似...

int main()
{
    HANDLE ff = startFFmpeg();
    if(ff != NULL)
    {
        // wait with periodic checks. this is setup for
        //  half-second checks. configure as you need
        while (WAIT_TIMEOUT == WaitForSingleObject(ff, 500))
        {
            // your wait code goes here.
        }

        // close the handle no matter what else.
        CloseHandle(ff);
    }
    return 0;
}

【讨论】:

  • 谢谢。让我试试这个。
  • @asprin 不要忘记您在pi 结构中拥有该进程句柄和它旁边的线程句柄。完成后你需要CloseHandle()他们两个(不,它不会终止进程,它只是释放句柄。)。
  • 如果您想检查进程是否仍在运行,那么您必须使用进程句柄,而不是 pid。 Pid 可以重复使用。
  • @WhozCraig 在其他部分,我使用了printf("running"),它正常输出。但是,在启动 ffmpeg 然后用任务栏关闭它后,我可以看到 ffpmeg 仍在将帧输出到输出文件夹。
  • @RaymondChen 在上面的例子中,是进程句柄吧?
【解决方案2】:

您不妨使用win32 api函数GetProcessId()

#include <windows.h>

...

BOOL bSuccess = FALSE;
LPTSTR pszCmd = NULL;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(si);

pszCmd = ... /* assign something useful */

bSuccess = CreateProcess(NULL, pszCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

if (bSuccess)
{
  DWORD dwPid = GetProcessId(pi.hProcess);
  ...
}
else
  ... /* erorr handling */

详情请看这里:http://msdn.microsoft.com/en-us/library/windows/desktop/ms683215%28v=vs.85%29.aspx

【讨论】:

  • 谢谢。这有帮助。您能否还举个例子说明如何在任务管理器中搜索dwPID,以便我知道它仍在运行?
  • HANDLE hPRocess = ? 里面会发生什么
  • 我收到hProcess undeclared (first use in this function) 编译错误
  • 啊!现在它说undefined reference to GetProcessId。我不是很喜欢 C
  • 您是否包含&lt;windows.h&gt;? @asprin
猜你喜欢
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2018-02-21
  • 2012-09-20
相关资源
最近更新 更多