【问题标题】:Check for a process previously started by the application always returns process alive检查应用程序先前启动的进程总是返回进程活动
【发布时间】:2014-03-20 08:39:44
【问题描述】:

我正在使用CreateProcess 创建一个进程:

  • 带有标志CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
  • InheritHandles 参数 = TRUE
  • startupinfo 标准输出和标准错误文件重定向 (STARTF_USESTDHANDLES)
  • SECURITY_ATTRIBUTES.InheritHandle = TRUE

进程在继续执行时关闭的句柄。

然后我通过获取具有给定 PID 的进程的句柄来检查进程状态:

HANDLE HProcess = OpenProcess( 
       PROCESS_QUERY_INFORMATION , TRUE, task->taskPid);

编辑:是的,我正在检查返回的进程是否真的是我查询的进程:

if ( ( HProcess != NULL ) && ( GetProcessId(HProcess) != requestedPid ) )

无论创建的进程是否真的在运行,我都会得到该进程的有效句柄。如果我重新启动我的应用程序,检查代码将正常工作。我怀疑句柄以某种方式被缓冲,或者创建的进程在同一个组中 - 但我似乎无法在文档中找到任何有关它的信息。

【问题讨论】:

  • 您获得的是the 进程的有效句柄还是a 进程的有效句柄?我认为 Windows 重用了进程标识符。
  • 这是 有效句柄。
  • 值得我阅读the documentation for OpenProcess,它引起了社区的好奇:当一个进程不存在时,OpenProcess 将一个句柄返回给下一个较低的进程 pid
  • 为什么不等待CreateProcess返回的进程句柄呢?
  • 它不值得作为答案发布,这是众所周知的事实:当进程退出时,处理的进程会发出信号。因此,您可以使用任何等待函数(如 WaitForSingleObject)来准确了解进程何时退出。重用进程句柄时,您的 GetExitCodeProcess 解决方法可能会失败。

标签: c windows winapi createprocess openprocess


【解决方案1】:

不能保证成功打开进程句柄就意味着该进程仍在运行。所以你描述的行为并不令人惊讶。

打开句柄后,您可以轻松检查该过程是否已完成:

DWORD dw = WaitForSingleObject(handle, 0);
if (dw == WAIT_OBJECT_0)
{
    // Process has exited
}

但是,您的方法一开始就有缺陷,因为您无法判断进程 ID 是否已被重用。不存储进程 ID,而是存储从 CreateProcess 返回的进程句柄,并使用它来测试进程退出,如图所示。

【讨论】:

    【解决方案2】:

    虽然这不是一个答案,但它确实可以作为一种解决方法

    拥有一个有效的句柄,可以检查进程是否完成:

    DWORD exitCode = 0;
    GetExitCodeProcess(HProcess, &exitCode);
    if (exitCode == STILL_ACTIVE ) {
      //task alive (or exited with STILL_ACTIVE :( )
    } else {
      //task exited with code exitCode
    }
    

    【讨论】:

    • 等待进程句柄发出信号要容易得多
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 2015-10-18
    相关资源
    最近更新 更多