为什么Process.WaitForExit会抛出一个“;无过程”;异常,即使进程确实存在

本文关键字:异常 过程 存在 进程 WaitForExit Process 一个 为什么 | 更新日期: 2023-09-27 18:22:08

我有一个包含以下代码的windows服务:

    public static void ExtractTextInner(string source, string destination)
    {   
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.FileName = EXTRACTOR_EXE_FILEPATH
        startInfo.Arguments = "'"" + source + "'" '"" + destination + "'"";
        startInfo.CreateNoWindow = true;
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();
        process.WaitForExit();
        int exitCode = process.ExitCode;
        process.Close();
        if (exitCode != 0)
        {
            switch (exitCode)
            {
                case 1:
                throw new ApplicationException("IFilter Extraction Failed");
                default:
                throw new ApplicationException("Unknown Exit Code:" + exitCode.ToString());
            }
        }
    }

这段代码的目的是在文档上运行IFilter提取,我们使用了一个单独的过程,因为有些IFilter是出了名的脆弱。

现在,此代码在Windows 7和Server 2008 R2框上运行得非常好,但在Windows Server 2003上,WaitForExit会立即抛出"没有进程与此进程对象关联"异常。该过程确实存在,并且毫无问题地完成了任务。

有人看到这个吗?有人能解释为什么WaitForExit会出现这个错误吗?

附加信息

如果我将此代码放在控制台应用程序中并在Windws Server 2003框中运行,它也可以正常工作,因此在Windows Server 2003框上的服务中运行此代码似乎是一个特定的问题。

为什么Process.WaitForExit会抛出一个“;无过程”;异常,即使进程确实存在

启动进程时,使用System.Diagnostics.Process类,系统可以使用CreateProcessShellExecuteEx Win32函数。使用CreateProcess时,只能启动可执行文件。当使用ShellExecuteEx时,可以使用shell中的"开始->运行"命令启动的任何文件。

然而,这些是完全不同的启动过程的方式。ShellExecuteEx涉及shell,例如,可以通过使用存储在HKCR'<progid>'shell'<verb>注册表项下的信息,重用Word或Excel的现有实例来打开文档。例如,这可能涉及使用DDE搜索并激活现有Excel实例。

参见ShellExecuteExSHELLEXECUTEINFO:文档

  • http://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx

注意,ShellExecuteEx可能返回也可能不返回hProcess,这取决于是否启动了新进程。这就是你所看到的行为。

CreateProcess是一个较低级别的函数,它直接创建一个进程,并简单地传递等价的参数。它总是返回一个进程句柄。

注意:由于您似乎正在启动一个可执行文件,因此ShellExecuteEx没有返回hProcess有点令人惊讶。尽管如此,如果您想确保获得流程句柄,使用UseShellExecute = false是正确的做法。