我有一个byte [],其中包含pdf文档的数据。我想通过将文件临时写入磁盘并使用Process.Start来启动pdf查看器,从而向用户显示此信息。用户查看并关闭文件后,我想将其删除,以免使用户的临时文件夹混乱。
此刻我的代码如下
public WritePdfDataToFile(byte[] pdfData, string tmpFileName)
{
using (var pdfFileStream = File.OpenWrite(tmpFileName))
{
pdfFileStream.Write(pdfData,0,pdfData.Length);
}
var process = Process.Start(tmpFileName);
process.EnableRaisingEvents = true;
process.Exited += (o,e) => File.Delete(tmpFileName);
}
现在,这种方法起初效果很好,并且弹出了我安装的PDF查看器,我看到了我的pdf,当我关闭它时,该文件会根据需要消失。
但是,如果我已经打开我选择的Pdf查看器,则可能会发生两种不同的情况。
Process.Start返回null,因为已经运行的进程正在处理该文件(已记录为here)
Process.Start返回一个几乎立即退出的进程-这是在我的计算机上本地发生的情况,我只能假定Acrobat Reader具有一些子进程来处理打开另一个文件并将其放在已经存在的选项卡中的情况。现有窗口。然后,它将关闭此子进程,并在Acrobat Reader中打开临时文件。
对我来说,我觉得我已经使用Process耗尽了所有选择。我没有办法解决这个问题。我不想阻塞并等待进程退出,并且由于该进程已经存在而导致进程为空,所以我不想按名称搜索该进程,因为我不知道用户计算机将使用哪个进程开始处理pdf文件。
我的另一个选择是显式创建FileStream并使用构造函数,该构造函数允许我指定在流关闭时应删除文件
using (var pdfStream = new FileStream(tempFileName,FileMode.Create, FileAccess.Write, FileShare.ReadWrite|FileShare.Delete,1024, FileOptions.DeleteOnClose))
{
pdfFileStream.Write(pdfData,0,pdfData.Length);
Process.Start(tempFileName);
}
这里有2个大问题
在进程启动之前,using语句退出(因此,在FileStream上调用dispose并删除了文件),因此它说找不到文件。我可以在启动过程之后但退出using语句作用域之前插入Thread.Sleep,但是其中一个将锁定线程,另外两个知道最终用户计算机的运行速度,所以我真的不喜欢
(至少在我的计算机上,使用Acrobat Reader),当我的应用程序仍具有流的句柄时,文件将不会打开
关于如何更好地做到这一点的任何建议?我觉得我可能不是唯一尝试过此方法的人,我在任何地方都找不到安全,可靠的建议。