2011-03-31 53 views
2

我正在嘗試編寫將用於將更新應用於應用程序的程序。由於應用程序的性質,某些文件將被鎖定(主要由IIS),並且不能使用File.Copy(target)覆蓋。當手動執行任務時,我們的支持團隊通常會使用Windows資源管理器複製文件,從而解鎖文件以允許他們複製新文件。使用Move覆蓋已鎖定的文件然後複製

爲什麼在使用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) 
} 

任何建議將是大。感謝您的幫助。

+2

究竟是什麼與Windows資源管理器一起工作並不十分清楚。顯然,資源管理器只是另一個應用程序,它確實給你「抱歉!」如果您嘗試移動/刪除鎖定文件就像其他任何錯誤。 – Jon 2011-03-31 22:01:05

+0

其實它完全有效。如果您嘗試刪除文件,它將失敗,但如果您嘗試移動或重命名文件,它將會成功。文件重命名後,您可以將新文件複製到之前鎖定的文件的位置。這可能是應用程序鎖定文件不是專門鎖定文件,而是阻止複製操作。 – smaclell 2011-03-31 22:09:56

+1

@smaclell:爲什麼你不試圖像單元測試那樣鎖定一個文件,直到按下一個鍵並查看Explorer如何處理它? – Jon 2011-03-31 22:11:55

回答

2

請注意,您的temp文件名無效,它缺少一個額外的反斜槓。

正在使用的重命名文件適用於爲其創建了內存映射文件的文件。與在進程中加載​​的.exe和.dll文件一樣。它不適用於使用FileStream打開的文件。這將會非常糟糕,Windows將無法在文件關閉時更新文件的元數據。像文件大小和上次寫入日期一樣。

這對於應用更新應該足夠好,您的代碼片段不會足夠好地模擬相同的操作。

2

無法在應用程序和Windows資源管理器中移動鎖定的文件。在軟件運行時執行更新的常用方法是將所有內容寫入臨時文件(例如program.exe.temp)。更新完成後,退出應用程序,將所有原始文件替換爲臨時文件(可能使用小型更新程序),然後重新啓動應用程序。這樣,您也可以取消更新過程(直到最後一步之前),而根本不會影響已安裝的版本。

1

請注意,你在哪裏有所作爲。你可以在本地逃脫,但不能遠程逃脫。並非所有的操作系​​統都允許它。