使用“移动然后复制”覆盖锁定的文件
我正在尝试编写一个程序,用于将更新应用于应用程序。由于应用程序的性质,某些文件将被锁定(主要由 IIS 锁定),并且无法使用 File.Copy(target)
进行覆盖。手动执行任务时,我们的支持团队通常会使用 Windows 资源管理器复制文件,该资源管理器会解锁文件,允许他们复制新文件。
为什么在使用 Windows 资源管理器执行此操作时会起作用,为什么在使用 Windows 资源管理器执行此操作时会失败得如此惨烈?代码?
我使用的代码大致如下:
File.Move( target, tempPath )
File.Copy( source, target )
通过打开并锁定文件的单元测试,然后尝试覆盖该文件:
var source = "c:\\source.txt";
var target = "c:\\target.txt";
var temp = "c:\\temp\\fake-target.txt";
using ( var lockedFile = System.IO.File.OpenWrite( target ) ) {
File.Move( target, temp )
File.Copy( source, target )
}
任何建议都会很棒。感谢您的帮助。
I am trying to write a program that will be used to apply updates to an application. Due to the nature of the application some of the files will become locked (primarily by IIS) and cannot be overwritten using File.Copy(target)
. When performing the task manually our support team will often copy the files using windows explorer which unlocks the file allowing them to copy the new one in.
Why does this work when doing it with Windows Explorer and why does it fail so miserably when doing it in code?
By code that I am using is roughly the following:
File.Move( target, tempPath )
File.Copy( source, target )
With a unit test that opens and locks a file that you then attempt to overwrite:
var source = "c:\\source.txt";
var target = "c:\\target.txt";
var temp = "c:\\temp\\fake-target.txt";
using ( var lockedFile = System.IO.File.OpenWrite( target ) ) {
File.Move( target, temp )
File.Copy( source, target )
}
Any suggestions would be great. Thank you for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请注意,您的 temp 文件名无效,缺少额外的反斜杠。
重命名正在使用的文件适用于为其创建了内存映射文件的文件。就像进程中加载的 .exe 和 .dll 文件一样。它不适用于使用 FileStream 打开的文件。这将是相当糟糕的,当文件关闭时,Windows 将无法更新文件的元数据。例如文件大小和上次写入日期。
这对于应用更新来说应该足够好了,您的代码片段根本无法很好地模拟相同的操作。
Note that your temp filename is invalid, it is missing an extra backslash.
Renaming files that are in use works for files that have a memory mapped file created for them. Like .exe and .dll files that are loaded in a process. It does not work for files that you open with a FileStream. That would be rather bad, Windows wouldn't be able to update the metadata for the file when the file is closed. Like the file size and last written date.
This should be good enough for applying updates, your code snippet simply doesn't emulate the same operation well enough.
您无法移动锁定的文件,无论是在应用程序中还是在 Windows 资源管理器中。在软件运行时执行更新的常用方法是将所有内容写入临时文件(例如program.exe.temp)。更新完成后,退出应用程序,用临时文件替换所有原始文件(可能使用小型更新程序),然后重新启动应用程序。这样,您还可以取消更新过程(直到最后一步之前),而不会干扰已安装的版本。
You cannot move locked files, neither in an application nor in the Windows Explorer. The usual way to perform an update while the software is running is to write everything to temporary files (e.g. program.exe.temp). When the update is complete, you exit the application, replace all original files with the temporary files (possibly using a small updater program), and restart the application. This way, you can also cancel the update process (until before the last step) without having interferred with the installed version at all.
请注意,您所在的位置会有所不同。您可以在本地解决此问题,但不能在远程解决此问题。并非所有操作系统都允许这样做。
Note that where you are makes a difference. You can get away with this locally but not remotely. Not all OSes permit it, either.