在我们的C#WinForms应用程序中,我们生成PDF文件并通过Process
类启动Adobe Reader(或任何默认系统.pdf处理程序)。由于我们的PDF文件可能很大(大约200K),我们处理Exited
事件然后清理临时文件。
打开文件然后再次关闭时,系统会根据需要运行。但是,当打开第二个文件时(关闭Adobe Reader之前),第二个进程会立即退出(因为Reader现在正在使用它的MDI权限)并且在我们的Exited
处理程序中,我们的File.Delete调用应该会失败,因为它被锁定了现在加入了Adobe流程。但是,在Reader中我们得到:
打开此文档时出错。找不到此文件。
不寻常的是,如果我在删除文件之前放置一个调试器断点并允许它尝试(并失败)删除,那么系统就会按预期运行!
我很肯定该文件存在且相当肯定,在启动该进程之前,所有处理/文件流都将关闭。
我们将使用以下代码启动:
// 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
来存储对Process对象的引用,以便它们保持在范围内,以便可以成功引发Exited事件。
我们的清理/退出活动是:
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
}
}
可能的解决方案:
答案 0 :(得分:3)
我只是几天前处理过这个问题。
当没有实例打开时,文档将直接在新实例中打开。
当一个实例已经打开时,我相信该实例会产生一个你实际上没有得到句柄的新实例。会发生什么情况是控制立即返回到您的函数,然后在新实例有机会读取文件之前删除文件 - 因此它似乎不在那里。
我通过不立即删除文件来“解决”这个问题,但是跟踪列表中的路径,然后在程序退出时对所有文件进行核对(将try / catch中的每个删除包装在一个空的catch块中)如果文件在此期间消失了。)
答案 1 :(得分:1)
我建议采用以下方法: