启动第二个实例时,Adobe读取器过程失败
-
12-10-2019 - |
题
在我们的C#Winforms应用程序中,我们生成PDF文件并通过启动Adobe读取器(或任何默认系统.pdf处理程序)通过 Process
班级。由于我们的PDF文件可能很大(约200K),我们处理 Exited
事件然后以后清理临时文件。
打开文件然后再次关闭时,该系统根据需要工作。但是,当打开第二个文件(在关闭Adobe阅读器之前)第二个过程立即退出(因为读者现在使用的是MDI powers),并且在我们的 Exited
处理程序我们的文件。删除调用应该失败,因为它已被现在加入的Adobe进程锁定。但是,在读者中,我们得到:
打开此文档的错误。该文件找不到。
不寻常的事情是,如果我将调试器断点放在文件删除之前,并允许其尝试(和失败)删除,那么系统将按预期行事!
我很肯定文件存在,并且相当阳性,所有处理/文件流都在开始过程之前关闭了文件/文件流。
我们正在使用以下代码启动:
// 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();
注意:我们正在使用 _pdfProcessDictionary
为了存储对过程对象的引用,以便它们保持在范围中,以便可以成功提出退出的事件。
我们的清理/退出活动是:
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
}
}
可能的解决方案:
- 检测该文件在另一个过程中仍打开
- 检测第二个过程尚未真正完全退出,并且文件在第一个过程中打开
解决方案
我 只是 几天前处理了这个。
如果已经没有实例打开,则该文档将直接在新实例中打开。
当实例已经打开时,我相信该实例会产生一个新实例,您实际上没有得到处理。发生的事情是立即返回您的函数,然后在新实例有机会读取文件之前删除文件 - 因此,它似乎不存在。
我通过不立即删除文件,而是跟踪列表中的路径,然后在程序退出时对所有路径进行“解决”(将每个删除在try/catch中用空捕获块中包装在try/catch中同时消失了)。
其他提示
我建议以下方法:
- 在用户的温度目录中创建文件(path.getTemppath)。您可以在其中创建一些子文件夹。
- 尝试仅在流程的最后一个实例退出时才尝试删除文件(即您需要计算启动,退出时启动的流程数量,减少计数,并且当它变为零时,尝试删除到目前为止打开的(所有)文件)
- 在启动和结束应用程序时,尝试清理创建的子文件夹(在临时目录下)。您甚至可以尝试使用计时器进行定期清理。
不隶属于 StackOverflow