.net 什么是Process.ExitTime上的InvalidOperationException;此对象未启动进程,因此无法确定请求的信息。”;

.net 什么是Process.ExitTime上的InvalidOperationException;此对象未启动进程,因此无法确定请求的信息。”;,.net,process,invalidoperationexception,.net,Process,Invalidoperationexception,我们有一个管理计算机多个进程的工具,在不确定的条件下,访问MSDN:属性时,我们会不时收到一个invalidooperationexception 异常消息显示 此对象未启动进程,因此请求了信息 无法确定 这是否意味着我只能得到我自己启动的流程的退出时间?这在任何地方都没有记录。根据示例,首先需要启动一个流程,然后需要等待它退出,此时可以获得myProcess.ExitCode值。可能您只是在创建的流程对象中填充了一些字段,但并没有启动它。另外,如果您想获取不允许控制的外部进程的退出时间,则需要

我们有一个管理计算机多个进程的工具,在不确定的条件下,访问MSDN:属性时,我们会不时收到一个
invalidooperationexception

异常消息显示

此对象未启动进程,因此请求了信息 无法确定


这是否意味着我只能得到我自己启动的流程的退出时间?这在任何地方都没有记录。

根据示例,首先需要启动一个流程,然后需要等待它退出,此时可以获得myProcess.ExitCode值。可能您只是在创建的流程对象中填充了一些字段,但并没有启动它。另外,如果您想获取不允许控制的外部进程的退出时间,则需要使用一些监视器或挂钩来获取退出时间。尽管如此,您提供的信息不足以理解您的意图,如果您不介意,请提供它。

为了访问退出时间信息,
进程
类需要有一个开放的进程句柄a。例如,
WaitForExit
将临时创建一个句柄,但不幸的是,它会在返回之前关闭该句柄

我们可以通过访问
进程的
句柄
安全句柄
属性,强制
进程
类永久打开该进程的句柄1。但是,我们应该注意,这里仍然存在一些冲突,因为在构造
进程
对象和访问
安全句柄
属性之间,进程可能会退出

启动记事本实例,找到其进程ID并将其编辑到
Main
的第一行:

using System;
using System.Diagnostics;

namespace PlayAreaCSCon
{
  internal class Program
  {
    public static void Main(string[] args)
    {
      var p = Process.GetProcessById(18148);
      //var sh = p.SafeHandle;
      p.WaitForExit();

      Console.WriteLine(p.ExitTime);
      Console.ReadLine();
    }
  }
}
一旦这个程序运行,退出记事本,观察我们得到了您提到的异常。清理并开始另一份记事本。这一次,在中编辑进程ID后,还要取消对提及
SafeHandle
的行的注释

一旦该程序再次运行,退出记事本。注意,这一次我们得到了退出时间。所以你有希望看到这个例外是如何产生的,我想我们都同意这个信息是非常不完整的


而且对于已经退出的进程,它无法使一个变为存在


1可能有很多额外的入口点会间接导致访问这些属性,从而对句柄产生副作用-但这些是强制打开句柄的最明显的途径。

这是一种设计选择,编写时假设程序员会忘记调用Process.Dispose()方法。每个人都是这样的,这会很快变得丑陋,操作系统进程对象很大。因此,它非常急切地释放Process.Handle,这会阻止它在进程终止时有效。您必须复制句柄和pinvoke GetProcessTimes()作为解决方法。感谢您为答案所做的努力。