我有一个基于MVC/C#的网站。正在使用的nuget包之一是一个围绕PDFium的包装器,PDFium是一个非.NET dll。PDFium dll是另一个nuget包的一部分,它只是一个复制到输出目录中的dll。
我遇到的问题是,在我使用网站后,PDFium dll(即非.net的dll,而不是正在进行包装的dll)似乎被加载,然后被IIS锁定。如果我尝试在Visual Studio中进行构建,我会收到一个错误:
无法复制文件[完整源路径]。进程无法访问文件[目标路径],因为另一个进程正在使用该文件。
构建错误日志中的第二行显示了类似的内容,并进一步确认:
文件由以下人员锁定:"IIS Worker Process(28776)">
如果我执行iisreset
,那么这将导致工作进程被终止,从而可能发生复制,但我想知道是否有更好的方法可以做到这一点。我的想法是,nuget软件包和类似软件包中包含的所有其他DLL都可以复制,所以也许可以做一些更"合适"的事情来解决这个问题,而不是使用稍微严厉的iisreset方法。。。
不确定这些是否会有所帮助,但为了避免IISReset,一个选项是确保IIS使用的PDFium.DLL不是在生成过程中复制到项目目标目录的PDFium。但是,如果PDFium.DLL必须与包装程序集位于同一个文件夹中(我怀疑它是这样),那么除了使用IISReset之外,您可能没有其他好的选择。您可以按照此处的建议(重新编译asp.net网站时如何重新启动IIS网站)添加预构建脚本,从而避免手动操作。
如果PDFium.DLL不必与包装器在同一文件夹中,并且可以在系统上的任何位置注册,则可以尝试将该引用的Copy Local属性设置为false,这样就不会尝试复制。显然,只有当包装器可以通过其注册表项找到DLL时,这才有效——如果它可以注册。。。
我们的构建报告了相同的错误,IIS锁定pdfium.dll导致构建失败。当我注意到它时,我会使用一个名为LockHunter的工具。
-
安装Lockhunter后,在文件资源管理器中查找由错误并右键单击它。
-
在上下文菜单中,LockHunter将添加一个菜单选项"是什么锁定了这个文件"-选择它。
-
将出现一个LockHunter窗口,报告文件被锁定w3wp.exe(IIS工作进程)。
-
LockHunter窗口有一个解锁文件的选项,请选择该选项。文件被解锁,然后构建工作。