我目前的一段代码有问题。当我通过Visual Studio 2013运行它和使用ClickOnce发布时,此代码在我的计算机上运行得非常好(即使没有一些额外的if语句(。在客户端计算机上,进程退出的事件处理程序捕获,进程 ID 正确,并且进程 .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);
}
}
事件处理程序中的 getReader 方法需要读取客户端必须签名的文件,因此必须事先将其关闭。我不能强制关闭,因为我永远不知道他们需要多长时间才能签名,而且我无法在他们签名并保存 pdf 之前发送电子邮件。
我已经尝试过使用 WaitForExit(( 方法,它完全跳过(仅在我客户的计算机上(。我运行的是 Windows 10,但客户端运行的是 Windows 7。我无法找到有关这些方法在Win7上不起作用的任何文档。
注意:我知道事件处理程序方法中的 if 语句有点多余,但我迫切希望找到它捕获的位置。
任何帮助将不胜感激。
修复:在我的 PDF 签名后,我最终弹出了一个消息框,以帮助后台工作线程中的 WaitForExit((。按下此消息框的"确定"按钮后(因为它们暂停应用程序并等待响应(,它将读取 pdf 文件。
它使用 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阅读器,则它将无法按预期工作