C#无法删除以前在窗口中打开的pdf
我有一个在窗口中打开的PDF文件。窗口关闭,然后我尝试删除该文件,并得到一个正在使用的错误。应该不再有锁了,因为打开它的窗户已经关上了。如有任何建议,将不胜感激 我有一个本地可变窗口C#无法删除以前在窗口中打开的pdf,c#,mvvm-light,C#,Mvvm Light,我有一个在窗口中打开的PDF文件。窗口关闭,然后我尝试删除该文件,并得到一个正在使用的错误。应该不再有锁了,因为打开它的窗户已经关上了。如有任何建议,将不胜感激 我有一个本地可变窗口 private Window _window; 我有以下代码在窗口中打开PDF _window = new Window { Title = "PDF Viewer", Content = new WebBrowserView(), DataContext = new WebBrow
private Window _window;
我有以下代码在窗口中打开PDF
_window = new Window
{
Title = "PDF Viewer",
Content = new WebBrowserView(),
DataContext = new WebBrowserViewModel
{
Uri = _pdfPathFull
},
IsEnabled = false
};
_window.Show();
窗口按如下方式关闭
private void ClosePDF()
{
if (_window != null)
{
window.DataContext = new WebBrowserViewModel
{
Uri = "about:blank"
};
_window.Close();
_window = null;
}
}
我有以下代码试图删除在窗口中打开的文件,但总是失败,错误为“进程无法访问文件\\ServerName\FileName.pdf,因为它正被另一个进程使用。”
我认为问题在于: 这样做:
DataContext = new WebBrowserViewModel
{
Uri = _pdfPathFull
},
在内存中创建一个对象,该对象即使在DataContext设置为“about:blank”时也会继续保存引用中的pdf
我建议使用一个参考变量来代替它。确保在窗口关闭后取消引用它。确保窗口对象也已从调用函数中清除
这就是我更新代码的方式:
添加新的专用变量:
private Window _window;
private FrameworkElement _fwElement;
下一组更改:
_fwElement = new FrameworkElement();
_fwElement.DataContext = new WebBrowserViewModel { Uri = _pdfPathFull };
_window = new Window
{
Title = "PDF Viewer",
Content = new WebBrowserView(),
DataContext = _fwElement.DataContext,
IsEnabled = false
};
_window.Show();
现在,当我们关闭窗口时:
private void ClosePDF()
{
if (_window != null)
{
if(_fwElement != null)
{
_fwElement.DataContext = null;
}
window.DataContext = new WebBrowserViewModel
{
Uri = "about:blank"
};
_fwElement = null;
_window.Close();
_window = null;
GC.Collect();
}
}
你的问题是什么
如果您想知道哪个进程正在锁定您的文件,一种简单的方法是运行openfiles/query/fotable
,并解析输出。有关如何获取输出,请参阅ProcessStartInfo.RedirectStandardOutput。如果是本地进程,则需要一次性安装,openfiles/local打开
并重新启动
顺便说一句,由于网络延迟,它可以锁定在插槽的两端,甚至在PC和\\ServerName
之间
对临时文件使用网络共享很少是个好主意。改为使用本地目录。如果由于法律或其他要求,您不能使用RAM而不是磁盘,例如,为嵌入式浏览器实施自定义URI方案,并以自定义方案URL提供pdf
更简单、更不可靠的解决方法是在延迟一段时间后重试删除该文件。我会使用100-500毫秒的延迟,并重试5-10秒。我在WinForms中遇到了这个问题,我发现唯一可靠的解决方法是制作PDF的临时副本并显示副本,这样原始文件就不会被锁定 据我所知,没有直接的方法指示webbrowser关闭文件
当然,您仍然需要删除临时副本,但您可以在下一次应用程序启动时删除,或者在计时器上继续重试,等等。将DataContext分配给其他对象只会孤立旧的副本,让它在程序运行时处理,而删除循环中的任何内容都不会这样做
这里有一个非托管资源,编译器不会为您清理。您必须明确地处理有问题的对象,并希望下面的代码编写得足够好。我从未对PDF文件尝试过这一点,在我对XPS文件的有限尝试中,我最终得到了SSS的解决方案(可以在下次运行程序时识别/删除的临时副本)。而不是window.DataContext=new WebBrowserViewModel{Uri=“about:blank”};尝试使用已存在的WebBrowserViewModel。所以试试:WebBrowserViewModel m=window.DataContext dt;m、 Uri=“关于:空白”。我认为仅更改数据内容不会从旧的WebBrowserViewModel卸载pdf。@Emanuele,这没有帮助。仍然得到相同的错误。我甚至添加了m.CleanUp();还是不走运。你用什么组件来显示pdf文件?如何读取文件?@EdneyHolder
WebBrowserViewModel
?展示这一点,以及在view@Nkosi我已经添加了定义。我尝试过延迟,但这不起作用。我不知道如何实现您在使用RAM实现自定义URI方案时提出的建议。请详细说明一下好吗?@edneyhold将PDF文件复制到MemoryStream。通过实现自定义URI模式处理程序将其传递给浏览器。这是我的老文章,其中有一个用于Windows窗体的库:它很可能也适用于WPF嵌入式web浏览器。你需要改变一件事。在CInternetProtocol::Start方法中,内容类型硬编码为内容类型:text/html;字符集=utf-8
。要提供PDF,您需要使用不同的字符串,application/PDF
your-answer向我展示了我想到的问题。由于调用需要一个url,您可以说明您建议如何使用引用变量吗
_fwElement = new FrameworkElement();
_fwElement.DataContext = new WebBrowserViewModel { Uri = _pdfPathFull };
_window = new Window
{
Title = "PDF Viewer",
Content = new WebBrowserView(),
DataContext = _fwElement.DataContext,
IsEnabled = false
};
_window.Show();
private void ClosePDF()
{
if (_window != null)
{
if(_fwElement != null)
{
_fwElement.DataContext = null;
}
window.DataContext = new WebBrowserViewModel
{
Uri = "about:blank"
};
_fwElement = null;
_window.Close();
_window = null;
GC.Collect();
}
}