System.Diagnostics.Process.HasExited始终返回true,并且当流程仍处于打开状态时,Process.Exited事件处理程序始终会命中

时间:2018-06-21 15:41:02

标签: c# .net wpf visual-studio-2013

我的部分代码目前有问题。当我通过Visual Studio 2013和使用ClickOnce进行发布时,此代码在我的计算机上运行良好(即使没有一些额外的if语句)。在客户端计算机上,退出进程的事件处理程序将捕获,进程ID是正确的,并且process.hasExited在进程仍处于打开状态时始终返回true。该过程将打开一个pdf文件供他们签名,并等待他们保存并关闭它,然后再继续操作。它使用Adobe Acrobat Reader DC。

收到的错误消息来自事件处理程序方法的catch块:

System.IO.IOException:该进程无法访问文件,因为它正在被另一个进程使用。

这是在调用getReaders_NewHire(emp)时发生的。

这是打开过程的方法:

private void pdfAndEmail(Employee employee, Requirements requirements)
    {
        try
        {
            PDFUtility pdfu = new PDFUtility();
            pdfu.createPDFMG_NewHire(employee, requirements);

            emp = employee;

            process = new System.Diagnostics.Process();
            string path = System.IO.Path.GetTempPath() + "\\ITResources\\Manager\\NewHire_" + employee.m_name.Replace(" ", "") + ".pdf";
            Uri pdf = new Uri(path, UriKind.RelativeOrAbsolute);
            process.StartInfo.FileName = pdf.LocalPath;
            process.EnableRaisingEvents = true;
            process.Exited += new EventHandler(process_Exited);
            process.Start();
            pid = process.Id;
        }

        catch (Exception e)
        {
            MessageBox.Show(e.ToString(), "Error Message", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

这是事件处理方法:

private void process_Exited(object sender, EventArgs e)
    {
        try
        {
            if (process.Id == pid)
            {
                if (process.HasExited)
                {
                    PDFUtility pdfu = new PDFUtility();
                    pdfu.getReaders_NewHire(emp);

                    Emailer send = new Emailer();
                    send.SendAfterMG_NewHire();
                }
                else
                    MessageBox.Show("Process has not exited.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString(), "Error Message", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

事件处理程序中的getReaders方法需要读取客户端必须签名的文件,因此必须事先关闭它。我无法强制关闭,因为我永远都不知道他们要签名需要多长时间,而且在他们签名并保存pdf之前我无法发送电子邮件。

我已经尝试过使用WaitForExit()方法,它会完全跳过(仅在客户端计算机上)。我正在运行Windows 10,但是客户端正在运行Windows7。我无法找到有关在Win7上不起作用的这些方法的任何文档。

注意:我知道事件处理程序方法中的if语句有点多余,但是我很想找到它在哪里捕获。

任何帮助将不胜感激。

已修复:我在签名PDF以协助Background Worker线程中的WaitForExit()之后弹出一个消息框。按下此消息框的“确定”按钮后(因为他们暂停了应用程序并等待响应),然后读取了pdf文件。

1 个答案:

答案 0 :(得分:0)

  

它使用Adobe Acrobat Reader DC。

我认为这是您的优势,我的方法假设了这一点。请考虑以下内容:

private static void Main()
{
    var process = Process.GetProcessesByName("AcroRd32").FirstOrDefault();
    if (process != null)
    {
        Process.Start(@"C:\mvvm.pdf");
    }
    else
    {
        process = Process.Start(@"C:\mvvm.pdf");
    }
    process.EnableRaisingEvents = true;
    process.Exited += (sender, args) =>
    {
        Console.WriteLine("Exited");
    };

    Console.ReadLine();
}

首先,我们检查Adobe进程是否已在运行,如果是,我们保留引用并将事件处理程序挂钩到该现有进程。如果没有,我们会做您已经做的事情。一些验证代码被省略。

我已经测试了正在运行的进程和未运行的进程,并且可以正常工作。

注意:如果用户将其他应用程序配置为预定义的PDF阅读器,则该功能将无法正常工作