﻿# 怪問題：當該檔案已經存在時，無法建立或陰影複製

我們有個網站專案，上週在客戶端開發程式時，由於不斷在更新程式，網頁上會不定時出現「當該檔案已經存在時，無法建立或陰影複製」的錯誤訊息，當下看到這個錯誤訊息感覺非常的陌生，我更新網頁程式跟「陰影複製」有何關係？由於該錯誤只要將 IIS 重啟或將應用程式集區回收即可解決，因此沒多留意，也沒將畫面複製下來，但我有用[這個技巧](/post/2008/08/08/Force-dot-Net-Application-output-English-exception-message)將錯誤訊息轉換成英文，好讓下次出現時可進一步分析發生原因。

果不其然，問題又再度發生，這次我就有將畫面複製下來了，如下圖所示，標紅框的地方是組件名稱，且每次出現錯誤的組件都不太一樣。

![Cannot create/shadow copy 'xVal' when that file already exists.](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e25a6882e79dc120442a-image.png "Cannot create/shadow copy 'xVal' when that file already exists.")

從網路上查到大部分資訊都是在開發時期所遇到的問題，但我這次是在客戶端的「模擬正式環境」遇到的，所以感覺很怪，因為怕他下次又再度發作，所以再努力搜尋資料查明原因，找了無數資料後終於瞭解原理。

原來 .NET Framework 有個 **陰影複製**(**Shadow Copy**) 機制，且早在 .NET 1.1 就有此機制，從網路搜查到的資料研判應該是在 ASP.NET 2.0 之後該機制預設是啟用的，可能是為了支援 ASP.NET 2.0 動態編譯架構的關係。

當你有新的組件部署到 bin\\ 目錄下時，被動態載入的組件會先被複製到一個稱為「陰影複製快取目錄」下，預設該目錄應該會放在 ASP.NET 的 Temporary ASP.NET Files 目錄下，然後 ASP.NET 的 AppDomain 會直接從這個目錄載入組件進並執行。這個機制最主要的目的是為了讓 bin\\ 目錄下的組件不被鎖定，以便於網站在運作的同時也能隨時更新 bin\\ 目錄下的組件，並重複 **陰影複製**(**Shadow Copy**) 的過程。

我所遇到的情況是更新的組件已經成功被複製進 bin\\ 目錄，但網頁並沒有反應更新後的功能，然後畫面就出現「當該檔案已經存在時，無法建立或陰影複製」這個錯誤訊息，這時只要強制回收應用程式集區就會回復正常。

而這台客戶提供的主機與我以往所部署過的主機相比，最主要的差別在於該主機是 Windows Server 2008 並啟用 UAC 機制（客戶要求不能關閉），由於該狀況為偶發，一星期也才發生三、四次，而且是在平凡更新程式的情況下遇到的，所以我不太確定是否跟 UAC 有直接關係，這也是我第一次預到這種錯誤。

在 [Microsoft Connect](https://developercommunity.visualstudio.com/) 網站查到的解決方案很多，不過官方的回應是「**已解決：不修正**」，但也有蠻多人提到可以透過修改 web.config 避免此問題發生，如果你經常在開發環境遇到此問題，建議可參考以下設定：

```
<system.web>   <hostingEnvironment shadowCopyBinAssemblies="false" /></system.web>
```

透過上述設定可關閉 ASP.NET 的 hostingEnvironment 的 **陰影複製**(**Shadow Copy**) 功能，雖然可避免此問題發生，但你很有可能就無法很順利的更新 bin\\ 目錄下的檔案了，因為檔案很可能會被鎖定！

所以我最後的解決方法也是「不修正」，因為日後在正式機上更新組件較不頻繁，所以應該沒必要為此做出修正，真的下次遇到問題只要將應用程式集區回收即可。

**相關連結**

-   [Shadow Copying Assemblies](http://msdn.microsoft.com/en-us/library/ms404279.aspx) / [陰影複製組件](http://msdn.microsoft.com/zh-tw/library/ms404279.aspx)
-   [Tip: Shadow Copy and your \\bin directory](http://blogs.msdn.com/gduthie/archive/2006/11/09/tip-shadow-copy-and-your-bin-directory.aspx)
-   [Cannot create/shadow copy when that file already exists](https://web.archive.org/web/20140118070429/http://neilkilbride.blogspot.com:80/2007/05/cannot-createshadow-copy-when-that-file.html)
-   Cannot create/shadow copy 'VariousFileName' when that file already exists.
-   [Cannot create/shadow copy problem in Visual Studio – arghhh](http://fatagnus.com/cannot-createshadow-copy-problem-in-visual-studio-arghhh/)
-   [Cannot create/shadow copy 'File Name' when that file already exists](http://blogs.msdn.com/tom/archive/2008/06/09/cannot-create-shadow-copy-file-name-when-that-file-already-exists.aspx)
-   [Asp.NET Runtime Hosting Update](https://weblog.west-wind.com/posts/2005/Jul/20/AspNET-Runtime-Hosting-Update)
-   [AppDomain and Shadow Copy](http://blogs.msdn.com/junfeng/archive/2004/02/09/69919.aspx)
-   [AppDomainSetup Members](http://msdn.microsoft.com/en-us/library/system.appdomainsetup_members.aspx)
-   [.NET Tips: ASP.NET](https://web.archive.org/web/20090413074129/http://msmvps.com:80/blogs/laflour/pages/net-tips-asp-net.aspx)
