C# 使用“移动然后复制”覆盖锁定的文件

C# 使用“移动然后复制”覆盖锁定的文件,c#,file-io,io,C#,File Io,Io,我试图写一个程序,将用于应用程序的更新。由于应用程序的性质,一些文件将主要由IIS锁定,无法使用File.Copytarget覆盖。当手动执行任务时,我们的支持团队通常会使用windows资源管理器复制文件,windows资源管理器会解锁文件,允许他们在中复制新文件 为什么在使用Windows资源管理器时可以这样做?为什么在代码中这样做会失败得如此惨重 我使用的代码大致如下: File.Move( target, tempPath ) File.Copy( source, target ) 使

我试图写一个程序,将用于应用程序的更新。由于应用程序的性质,一些文件将主要由IIS锁定,无法使用File.Copytarget覆盖。当手动执行任务时,我们的支持团队通常会使用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 )
}

任何建议都很好。感谢您的帮助。

您无法在应用程序或Windows资源管理器中移动锁定的文件。软件运行时执行更新的常用方法是将所有内容写入临时文件,例如program.exe.temp。更新完成后,退出应用程序,可能使用小型更新程序将所有原始文件替换为临时文件,然后重新启动应用程序。这样,您也可以在最后一步之前取消更新过程,而不会与安装的版本发生任何冲突。

请注意,您的临时文件名无效,缺少一个额外的反斜杠

重命名正在使用的文件适用于为其创建内存映射文件的文件。类似于进程中加载的.exe和.dll文件。它不适用于使用FileStream打开的文件。这将非常糟糕,当文件关闭时,Windows将无法更新该文件的元数据。例如文件大小和上次写入日期


这对于应用更新来说应该足够好了,因为您的代码片段不能很好地模拟相同的操作。

请注意,您所在的位置会有所不同。您可以在本地解决此问题,但不能远程解决。也不是所有操作系统都允许这样做。

不太清楚Windows资源管理器到底在使用什么。显然,资源管理器只是另一个应用程序,它确实让您感到抱歉!如果您尝试像其他文件一样移动/删除锁定的文件,则会出现错误。实际上,它完全有效。如果您尝试删除文件,它将失败,但如果您尝试移动或重命名文件,它将成功。重命名文件后,可以在锁定文件之前的位置复制新文件。可能是锁定文件的应用程序并不是专门锁定文件,而是阻止复制操作。@smaclell:为什么不尝试在单元测试中锁定文件,直到按下一个键,然后查看资源管理器如何处理?好建议。我尝试了System.IO.FileAccess和System.IO.FileShare的所有组合。只有System.IO.FileShare.Delete允许您移动文件。这必须是IIS锁定文件的方式,除非它正在执行非标准的其他操作。@smaclell:有关其他信息,您可以将Process Monitor挂接到Process/Win资源管理器中,以查看它进行的API调用以及它们返回的内容: