2010-06-22 275 views
20

我有一個Visual Studio 2008項目,我「升級」到Visual Studio 2010.自升級以來,我一直在項目中遇到很多問題(一個項目當時仍然是項目管理員在2008年我可能會補充)。Visual Studio 2010構建文件鎖定問題

第一個問題是構建主要可執行文件會鎖定可執行文件,導致進一步的重建失敗。這是在一個相關的問題描述:Visual Studio locks output file on build,我拿起了解決方法:

if exist "$(TargetPath).locked" del "$(TargetPath).locked" 
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked" 

除了這種解決方法的工作原理完全一次。 .locked文件然後被devenv.exe鎖定,並且必須移動。我一直在通過添加.1.locked,.2.locked等來解決這個問題。只有在關閉devenv.exe時纔會關閉鎖,因此文件可以是已刪除(這需要幾秒鐘的時間UI消失,那麼文件可以被刪除)。

調試器不必被用來引發這個問題的事實指出了2010構建系統的一個非常嚴重的問題。

一些理論,我想我可以打折:

  • 殺毒軟件或其它後臺任務:如果這是一個問題,它似乎2008年會失敗。然而,作爲一個完整的我刪除了avast!系統完全沒有運氣。

更新:此項目在沒有防病毒和無備份實用程序的機器上具有相同的症狀。在辦公室的機器運行XP SP3 32位,我的本地機器是Windows 7 64位。這看起來與操作系統無關。

  • 調試器正在鎖定文件:重現此操作所需的所有內容都將重複構建過程而不進行調試。 ProcessExplorer顯示devenv.exe是鎖的持有者,而不是vshost,並且殺死vshost.exe並不會移除鎖。

我有一個第二個問題,一旦文件被鎖定就開始出現:表單設計器停止加載「找不到程序集」錯誤。我懷疑這些問題與早期的鎖定問題有關,因爲設計人員將之前的加入到構建中,但做出任何更改和重新構建都會導致所有設計人員崩潰(即使是我已打開並且作爲當前視圖)。

僅僅因爲您將「dummy = 1」更改爲「dummy = 2」而在接近白色錯誤屏幕的位置觀看錶單是一個可憐的事情,其中​​「dummy」完全不了了之,只是在完全不相關的程序集中強制重新編譯。

更新:我已經嘗試了幾個補救措施:啓用.NET源步進沒有被選中,所以這不是問題。刪除.SUO(解決方案用戶選項)只需重新啓動就可以解決問題(兩個版本:第一個,因爲沒有鎖定的文件,第二個是因爲有一個,但可以通過腳本重命名)。

Error 28 Unable to copy file "obj\Debug\PolicyTracker3.exe" to "bin\Debug\PolicyTracker3.exe". 
The process cannot access the file 'bin\Debug\PolicyTracker3.exe' because it is being used by another process. 
+0

你有沒有解決過這個問題? – 2010-07-21 20:24:23

+0

只要我在這裏得到的唯一答案中的信息,提到的功能(.NET框架源)未啓用,並且從未啓用。 – Godeke 2010-07-28 19:09:44

+0

爲了記錄,我也遇到了這個問題,並且解決方案也是從2008年開始轉換的,所以也許這與它有關。我沒有得到表單設計師的問題,但其他的幾乎和你描述的完全一樣。 – 2010-08-14 17:53:39

回答

15

直到一個補丁繞過這個,我有以下解決方法。只需撥打"C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)"(將MyBin替換爲您放置可執行文件的位置)即可。

將其作爲C#控制檯應用程序創建,並以與原始構建前重命名相同的方式(請參閱原始問題的頂部以獲取詳細信息)用於構建前部分。

using System; 
using System.IO; 

namespace VisualStudioLockWorkaround 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
    string file = args[0]; 
    string fileName = Path.GetFileName(file); 
    string directory = Path.GetDirectoryName(args[0]); 
    if (!Directory.Exists(directory)) //If we don't have a folder, nothing to do. 
    { 
    Console.WriteLine(String.Format("Folder {0} not found. Exiting.", directory)); 
    return; 
    } 
    if (!File.Exists(file)) //If the offending executable is missing, no reason to remove the locked files. 
    { 
    Console.WriteLine(String.Format("File {0} not found. Exiting.", file)); 
    return; 
    } 
    foreach (string lockedFile in Directory.EnumerateFiles(directory, "*.locked")) 
    { 
    try //We know IOExceptions will occur due to the locking bug. 
    { 
     File.Delete(lockedFile); 
    } 
    catch (IOException) 
    { 
     //Nothing to do, just absorbing the IO error. 
    } 
    catch (UnauthorizedAccessException) 
    { 
     //Nothing to do, just absorbing the IO error. 
    }           
    } 

    //Rename the executable to a .locked 
    File.Move(file, Path.Combine(directory, String.Format("{0}{1:ddmmyyhhmmss}.locked", fileName, DateTime.Now))); 
    } 
    } 
} 
+0

修改爲包含UnauthorizedAccessException。好奇,如果這只是一個鎖定的文件拋出(顯然我期待的是IOException)或者它指向了部分問題? – Godeke 2010-08-10 16:50:30

+0

超好的回答 – 2015-10-26 20:57:26

3

有在.NET Framework的源已知的文件句柄泄漏的bug步進功能。通過在Tools + Options + Debugger中關閉該選項很容易避免。然而,如果你從未得到調試器,那麼這不太可能成爲你的問題。

很不清楚爲什麼Visual Studio會在構建輸出中感興趣,更不用說加載並鎖定它。也許你曾經打開.exe一次?確保在解決方案目錄中刪除隱藏的.suo文件。 connect.microsoft.com上沒有任何與您的問題相匹配的反饋報告,我建議您開始自己的問題。他們需要一些可重現的東西來看看它,確保你包含一個展示這種行爲的示例項目。

+0

你有沒有參考源步進問題?我在2008年找到了它的參考資料,但他們聲稱它在2010年得到了修正(這與我的經驗完全相反)。並不是說它是構建問題的主要關注點,但我只是對細節感到好奇。 – Godeke 2010-06-22 18:36:38

+0

我在瀏覽連接報告時找到了它。這是一個2010年的問題。由於失去了鏈接,我相信你可以找回它。 – 2010-06-22 18:42:11

+0

奇怪的是,加入.suo文件似乎有些不同。我會假設轉換以某種方式破壞了它(儘管我希望在轉換過程中將它刪除以實現誠實)。 – Godeke 2010-06-22 19:43:00

2

不幸的是,重命名/移動鎖定的文件對我來說不起作用(句柄只用FILE_SHARE_READ打開),但是有效的只是在Visual Studio進程中殺死了那些(大概是泄露的)句柄。您可以使用KillHandle自動執行此步驟。

+0

KillHandle沒有爲我工作。它在進程0x00000060上打印出「KillHandle:Killed handle 0x000036F0」,但VS仍然有文件鎖定。 – serg 2012-09-12 10:47:25

1

對我而言,我爲Visual Studio 2010中的擴展創建了一個高度自定義的構建,它在Visual Studio 2008中沒有問題。在構建的一個點上,一些輸出構件被加載到一個單獨的應用程序域中文檔生成,然後卸載域。域卸載工作正常,通過檢查前後的應用域列表來確認。

Visual Studio 2010似乎在任何使用基於文件句柄或路徑操作的基於文件的Assembly.Load * API加載的程序集上保存文件句柄鎖。一旦Assembly.Load執行後,我就可以看到文件句柄出現在ProcessExplorer中,並且即使在卸載AppDomain之後也不會釋放句柄。

我能夠通過使用FileStream和byte [] Assembly.Load重載加載原始裝配字節來解決問題。

0

我對派對有點遲到,但是這個問題在升級到VS2015後第一次發生。 VS2010從來沒有發生過!

我們經常開發同時打開VS的多個實例 - 這是一個客戶端/服務器應用程序,我們正在同時對兩個層進行更改。

升級到VS2015後,VS的兩個實例會互相「鎖定」obj \ Debug,一個實例最終無法構建通用(「共享」)項目,即我們的DTO實體框架項目。

我嘗試了預編譯腳本,它有時會起作用。這對我們的案例來說是不可靠的 - 有時DLL會被鎖定,甚至無法重命名/移動。

我最終只爲每個解決方案使用了不同的解決方案構建配置(從Debug中複製)。這創建了新的解決方案特定的obj和bin目錄,並完全避免了與常見項目相關的dll爭用。

希望這可以幫助別人。