当进程 ID 不再是 运行 时,为什么 OpenProcess() return 是一个非 0 值
Why does OpenProcess() return a non 0 value when the process ID is no longer running
我正在使用 Example 中的 CreateProcess
启动另一个应用程序的新实例,我最终保存了 PID,以便稍后检查该进程是否仍在 运行 .
我正在使用以下方法检查它是否 运行:
procedure TfrmRSM.Button1Click(Sender: TObject);
begin
var
ahandle := OpenProcess(PROCESS_ALL_ACCESS, true, aPID);
if ahandle = 0 then
ShowMessage('is not running')
else
ShowMessage('is running');
CloseHandle(ahandle);
end;
上面的代码应该 return 0
当进程不再 运行 但它仍然 return 是一个大于 0
[=17 的数字=]
我在使用 CreateProcess 后关闭句柄
如果我使用的方法不正确,有什么正确的方法来检查 PID 是否 运行?我只能找到使用应用程序名称的方法。
要等待进程结束,只需在进程句柄上使用WaitForSingleObject()
:当进程结束时,句柄发出信号,函数returns WAIT_OBJECT_0
。这样可以确保您在手柄存在的整个过程中都在“查看”手柄,而不是只是时不时地检查一下,否则就无人看管。
您很可能将它放入一个单独的线程中,并且在它结束时您有您的事件来对监视的进程何时结束做出反应。如果您有多个句柄要查找,请使用 WaitForMultipleObjects()
- 请注意它不能一次处理超过 64 (MAXIMUM_WAIT_OBJECTS
) 个句柄。
编辑: 当无法完全跟踪进程句柄时,您至少可以使用 GetProcessTimes()
检查您正在查看的进程是否仍在开始与您上次查看它的时间相同 - 这应该使它非常与众不同:当进程句柄被新进程回收时,至少它的开始时间应该不同。
Why does OpenProcess() return a non 0 value when the process ID is no
longer running?
这可能是未定义的行为或 PID 已被 Windows 回收。
I want to check if a process I created is still running later even
after I quit my application and opened it again.
你说你不能改变这个过程。一种解决方法是使用中间且非常简单的流程来启动目标流程。中间进程可以使用任何 IPC(例如共享文件的共享内存)与主进程通信,以通知它有关 运行ning 目标进程的信息。这个中间进程将 运行 目标进程并更新主进程可以查询的标志(在我的共享内存示例中)。
中间进程还可以在目标进程 运行ning 时保持文件打开以进行独占访问。主进程可以尝试打开文件,如果成功,则目标进程完成(中间进程使用WaitForSingleObject
或WaitForMultipleObject
等待目标进程终止)。
I'm starting a new instance of another application using CreateProcess from Example and I end up saving the PID so that I can later check if that process is still running.
正确的处理方法是把CreateProcess()
给你的HANDLE
一直打开,然后你可以通过WaitForSingleObject()
或GetExitCodeProcess()
查询看看如果进程已终止,则在不再需要时关闭 HANDLE
。
在评论中,您提到您的启动应用程序可能会终止并独立于目标进程重新启动。在这种情况下,您可以关闭 HANDLE
如果您仍然打开它,将其 PID 和创建 date/time 保存在您可以从中取回的地方,然后当您的应用程序重新启动时它可以 enumerate running processes (alternatively) 查看目标 EXE 是否仍然是 运行 并且具有匹配的 PID 和 date/time,如果是,则为该 PID 打开一个新的 HANDLE
。请小心,因为这确实引入了一个小的竞争条件,目标进程可能会在您检测到它的存在后终止,并且它的 PID 可能会在您有机会打开它之前被回收。因此您可能需要在打开 HANDLE
后重新验证它的信息。
否则,在您的应用程序关闭期间(甚至之前),您可以将打开的 HANDLE
从 CreateProcess()
卸载到一个单独的辅助进程,该进程在后台保持 运行监控 HANDLE
,然后您的主应用程序可以在重新启动后从该帮助器获取 HANDLE
。或者,首先在助手中执行实际的 CreateProcess()
调用,这样 HANDLE
监控始终保持在单个进程中,并让您的主应用程序在需要时查询助手的状态。
I'm using to following method to check if it's running or not:
那是行不通的,因为您不知道 PID 是否仍然有效,甚至不知道是否仍然引用您感兴趣的同一个进程。一旦该进程终止,它的 PID 可以随时回收用于新工艺。
The code above should return 0 when the process is no longer running but it still returns a number greater than 0
OpenProcess()
可以 return 非零的唯一方法是如果指定的 PID 实际上是 运行。但这并不能保证它是您感兴趣的相同过程。至少,在 OpenProcess()
return 一个非零 HANDLE
之后,您可以查询 HANDLE
获取其信息(EXE 文件路径、创建 date/time 等)以查看它是否与您期望的过程相同。如果信息不匹配,则 PID 被回收。
我正在使用 Example 中的 CreateProcess
启动另一个应用程序的新实例,我最终保存了 PID,以便稍后检查该进程是否仍在 运行 .
我正在使用以下方法检查它是否 运行:
procedure TfrmRSM.Button1Click(Sender: TObject);
begin
var
ahandle := OpenProcess(PROCESS_ALL_ACCESS, true, aPID);
if ahandle = 0 then
ShowMessage('is not running')
else
ShowMessage('is running');
CloseHandle(ahandle);
end;
上面的代码应该 return 0
当进程不再 运行 但它仍然 return 是一个大于 0
[=17 的数字=]
我在使用 CreateProcess 后关闭句柄
如果我使用的方法不正确,有什么正确的方法来检查 PID 是否 运行?我只能找到使用应用程序名称的方法。
要等待进程结束,只需在进程句柄上使用WaitForSingleObject()
:当进程结束时,句柄发出信号,函数returns WAIT_OBJECT_0
。这样可以确保您在手柄存在的整个过程中都在“查看”手柄,而不是只是时不时地检查一下,否则就无人看管。
您很可能将它放入一个单独的线程中,并且在它结束时您有您的事件来对监视的进程何时结束做出反应。如果您有多个句柄要查找,请使用 WaitForMultipleObjects()
- 请注意它不能一次处理超过 64 (MAXIMUM_WAIT_OBJECTS
) 个句柄。
编辑: 当无法完全跟踪进程句柄时,您至少可以使用 GetProcessTimes()
检查您正在查看的进程是否仍在开始与您上次查看它的时间相同 - 这应该使它非常与众不同:当进程句柄被新进程回收时,至少它的开始时间应该不同。
Why does OpenProcess() return a non 0 value when the process ID is no longer running?
这可能是未定义的行为或 PID 已被 Windows 回收。
I want to check if a process I created is still running later even after I quit my application and opened it again.
你说你不能改变这个过程。一种解决方法是使用中间且非常简单的流程来启动目标流程。中间进程可以使用任何 IPC(例如共享文件的共享内存)与主进程通信,以通知它有关 运行ning 目标进程的信息。这个中间进程将 运行 目标进程并更新主进程可以查询的标志(在我的共享内存示例中)。
中间进程还可以在目标进程 运行ning 时保持文件打开以进行独占访问。主进程可以尝试打开文件,如果成功,则目标进程完成(中间进程使用WaitForSingleObject
或WaitForMultipleObject
等待目标进程终止)。
I'm starting a new instance of another application using CreateProcess from Example and I end up saving the PID so that I can later check if that process is still running.
正确的处理方法是把CreateProcess()
给你的HANDLE
一直打开,然后你可以通过WaitForSingleObject()
或GetExitCodeProcess()
查询看看如果进程已终止,则在不再需要时关闭 HANDLE
。
在评论中,您提到您的启动应用程序可能会终止并独立于目标进程重新启动。在这种情况下,您可以关闭 HANDLE
如果您仍然打开它,将其 PID 和创建 date/time 保存在您可以从中取回的地方,然后当您的应用程序重新启动时它可以 enumerate running processes (alternatively) 查看目标 EXE 是否仍然是 运行 并且具有匹配的 PID 和 date/time,如果是,则为该 PID 打开一个新的 HANDLE
。请小心,因为这确实引入了一个小的竞争条件,目标进程可能会在您检测到它的存在后终止,并且它的 PID 可能会在您有机会打开它之前被回收。因此您可能需要在打开 HANDLE
后重新验证它的信息。
否则,在您的应用程序关闭期间(甚至之前),您可以将打开的 HANDLE
从 CreateProcess()
卸载到一个单独的辅助进程,该进程在后台保持 运行监控 HANDLE
,然后您的主应用程序可以在重新启动后从该帮助器获取 HANDLE
。或者,首先在助手中执行实际的 CreateProcess()
调用,这样 HANDLE
监控始终保持在单个进程中,并让您的主应用程序在需要时查询助手的状态。
I'm using to following method to check if it's running or not:
那是行不通的,因为您不知道 PID 是否仍然有效,甚至不知道是否仍然引用您感兴趣的同一个进程。一旦该进程终止,它的 PID 可以随时回收用于新工艺。
The code above should return 0 when the process is no longer running but it still returns a number greater than 0
OpenProcess()
可以 return 非零的唯一方法是如果指定的 PID 实际上是 运行。但这并不能保证它是您感兴趣的相同过程。至少,在 OpenProcess()
return 一个非零 HANDLE
之后,您可以查询 HANDLE
获取其信息(EXE 文件路径、创建 date/time 等)以查看它是否与您期望的过程相同。如果信息不匹配,则 PID 被回收。