[英]Adobe Reader process fails when starting second instance
In our C# WinForms application, we generate PDF files and launch Adobe Reader (or whatever the default system .pdf handler is) via the Process
class. 在我们的C#WinForms应用程序中,我们通过
Process
类生成PDF文件并启动Adobe Reader(或任何默认系统.pdf处理程序)。 Since our PDF files can be large (approx 200K), we handle the Exited
event to then clean up the temp file afterwards. 由于我们的PDF文件可能很大(大约200K),我们处理
Exited
事件然后清理临时文件。
The system works as required when a file is opened and then closed again. 打开文件然后再次关闭时,系统将根据需要运行。 However, when a second file is opened (before closing Adobe Reader) the second process immediately exits (since Reader is now using it's MDI powers) and in our
Exited
handler our File.Delete call should fail because it's locked by the now joined Adobe process. 但是,当打开第二个文件时(关闭Adobe Reader之前),第二个进程立即退出(因为Reader现在正在使用它的MDI权限)并且在我们的
Exited
处理程序中,我们的File.Delete调用应该失败,因为它被现在加入的Adobe进程锁定。 However, in Reader we instead get: 但是,在Reader中,我们得到:
There was an error opening this document.
打开此文档时出错。 This file cannot be found.
找不到此文件。
The unusual thing is that if I put a debugger breakpoint before the file deletion and allow it to attempt (and fail) the deletion, then the system behaves as expected! 不寻常的是,如果我在删除文件之前放置一个调试器断点并允许它尝试(并失败)删除,那么系统就会按预期运行!
I'm positive that the file exists and fairly positive that all handles/file streams to the file are closed before starting the process. 我很肯定该文件存在并且相当肯定,在启动进程之前,文件的所有句柄/文件流都已关闭。
We are launching with the following code: 我们将使用以下代码启动:
// Open the file for viewing/printing (if the default program supports it)
var pdfProcess = new Process();
pdfProcess.StartInfo.FileName = tempFileName;
if (pdfProcess.StartInfo.Verbs.Contains("open", StringComparer.InvariantCultureIgnoreCase))
{
var verb = pdfProcess.StartInfo.Verbs.First(v => v.Equals("open", StringComparison.InvariantCultureIgnoreCase));
pdfProcess.StartInfo.Verb = verb;
}
pdfProcess.StartInfo.Arguments = "/N"; // Specifies a new window will be used! (But not definitely...)
pdfProcess.SynchronizingObject = this;
pdfProcess.EnableRaisingEvents = true;
pdfProcess.Exited += new EventHandler(pdfProcess_Exited);
_pdfProcessDictionary.Add(pdfProcess, tempFileName);
pdfProcess.Start();
Note: We are using the _pdfProcessDictionary
to store references to the Process objects so that they stay in scope so that Exited event can successfully be raised. 注意:我们使用
_pdfProcessDictionary
来存储对Process对象的引用,以便它们保持在范围内,以便可以成功引发Exited事件。
Our cleanup/exited event is: 我们的清理/退出活动是:
void pdfProcess_Exited(object sender, EventArgs e)
{
Debug.Assert(!InvokeRequired);
var p = sender as Process;
try
{
if (_pdfProcessDictionary.ContainsKey(p))
{
var tempFileName = _pdfProcessDictionary[p];
if (File.Exists(tempFileName)) // How else can I check if I can delete it!!??
{
// NOTE: Will fail if the Adobe Reader application instance has been re-used!
File.Delete(tempFileName);
_pdfProcessDictionary.Remove(p);
}
CleanOtherFiles(); // This function will clean up files for any other previously exited processes in our dictionary
}
}
catch (IOException ex)
{
// Just swallow it up, we will deal with trying to delete it at another point
}
}
Possible solutions: 可能的解决方案:
I just dealt with this a couple of days ago. 我刚刚在几天前处理过这个问题。
When there is no instance open already, the document opens in a new instance directly. 当没有实例打开时,文档将直接在新实例中打开。
When there is an instance already open, I believe that instance spawns a new instance which you don't actually get a handle to. 当一个实例已经打开时,我相信该实例会产生一个你实际上没有得到句柄的新实例。 What happens is control returns to your function immediately, which then goes and deletes the file before the new instance has had a chance to read the file -- hence it appears to not be there.
发生的是控制立即返回到您的函数,然后在新实例有机会读取文件之前删除文件 - 因此它似乎不在那里。
I "solved" this by not deleting the files immediately, but keeping track of the paths in a list, and then nuking all of them when the program exits (wrap each delete in a try/catch with an empty catch block in case the file has disappeared in the meantime). 我通过不立即删除文件来“解决”这个问题,但是跟踪列表中的路径,然后在程序退出时对所有文件进行核对(在try / catch中使用空catch块包装每个删除以防文件在此期间已经消失了)。
I would suggest following approach: 我建议采用以下方法:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.