Asp.net

System.Web.MVC 自 MS14-059 以來未復製到 bin 文件夾中。如何防止由於 Windows 更新而創建缺少 DLL 的建構?

  • October 20, 2014

今天早上有報導稱,我們的 QA 伺服器上的 Web 應用程序完全損壞,Web.config 報告了以下錯誤:

無法載入文件或程序集“System.Web.Mvc,Version=5.1.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”或其依賴項之一。該系統找不到指定的文件

記得看到提到 MVC 的 Windows 更新,我做了一些探勘,發現很多人報告 最近 Windows 更新破壞了 MVC。

在對這些問題和我們的伺服器進行了大量探勘之後,似乎我們被咬的東西與其他問題中的東西不匹配,但它看起來確實相關。以下是我們認為知道的:

  • 我們損壞的應用程序使用 ASP.NET MVC 5.1
  • MVC 是通過 NuGet 安裝的
  • 我們的 BuildServer 和 QA 伺服器沒有安裝 MVC 5.1(因此,不是 GAC’d)

我們認為已損壞的內容導致創建了“不良建構”:

  • 儘管 GAC 中沒有安裝 MVC 5.1,但通過 Windows 更新在 BuildServer 上安裝了 MVC 5.1 的更新檔
  • 該更新檔已將 MVC 5.1 的“更新”版本放入 GAC
  • 當 DLL 在 GAC 中時,CopyLocal=true 會被忽略;因此,自更新檔以來,這意味著從 BuildServer 建構我們的應用程序的輸出文件夾中不再有 System.Web.MVC
  • 由於 System.Web.MVC 不在我們的 QA 伺服器上的 GAC 中(它們尚未打更新檔),因此應用程序現在失敗,因為找不到 System.Web.MVC

假設上述行為是正確的,這意味著任何時候 MS 通過 Windows 更新為我們在 GAC 中沒有的 NuGet DLL 提供服務,我們的 BuildServer 將開始生成不完整的建構(錯過那些已註入 GAC 的 DLL) .

升級到 MVC 5.2 解決了這個問題(可能是因為它沒有打更新檔,因此沒有註入 GAC);DLL 現在被複製到輸出文件夾。升級到 5.2.2 的差異沒有任何變化,除了版本號更改(特別是沒有<Private>添加/編輯節點)。

我們不希望開始對所有內容進行 GAC,也不希望創建手動建構步驟來將我們所有的 DLL 複製到bin文件夾中,以防萬一 MS 修補它們。

那麼,如果 MS 將來修補其他 DLL,我們今天可以改變什麼來確保我們不會最終導致 BuildServer 默默地產生錯誤的建構?

> > 儘管 GAC 中沒有安裝 MVC 5.1,但通過 Windows 更新在 BuildServer 上安裝了 MVC 5.1 的更新檔 > > >

是的,這種行為實際上是設計使然。請參閱<http://blogs.msdn.com/b/dotnet/archive/2014/01/22/net-4-5-1-supports-microsoft-security-updates-for-net-nuget-libraries.aspx>。


> > 該更新檔已將 MVC 5.1 的“更新”版本放入 GAC > > >

對,那是正確的; 這就是更新檔如何讓更新的程式碼而不是舊程式碼執行。請參閱<https://technet.microsoft.com/en-us/library/security/ms14-059>。


> > 當 DLL 在 GAC 中時,CopyLocal=true 會被忽略;因此,自更新檔以來,這意味著從 BuildServer 建構我們的應用程序的輸出文件夾中不再有 System.Web.MVC > > >

不完全是。實際發生的是一個以前是 CopyLocal=true 的項目被切換到 CopyLocal=false。CopyLocal 可以通過以下兩種方式之一進行設置:1) 如果&lt;Private&gt;True&lt;/Private&gt;.csproj 文件中有顯式設置,或 2) 預設情況下,如果不存在此類設置(GAC 的程序集預設不 CopyLocal;其他程序集有)。

因此,在這種情況下似乎發生的是您的項目文件在 csproj 文件中沒有此設置。結果,GUI 顯示了基於更新檔之前評估的預設值的設置(CopyLocal = true),但在安裝更新檔之後,GUI 現在將顯示 GAC 程序集的新預設值(CopyLocal = false )。


> > 由於 System.Web.MVC 不在我們的 QA 伺服器上的 GAC 中(它們尚未打更新檔),因此應用程序現在失敗,因為找不到 System.Web.MVC > > >

這是正確的。


> > 假設上述行為是正確的,這意味著任何時候 MS 通過 Windows 更新為我們在 GAC 中沒有的 NuGet DLL 提供服務,我們的 BuildServer 將開始生成不完整的建構(錯過那些已註入 GAC 的 DLL) . > > >

對於沒有明確&lt;Private&gt;True&lt;/Private&gt;設置的任何 .csproj 引用,這是正確的。此外,請注意使用 NuGet 更新您的 MVC 引用可以刪除此設置,即使它以前存在。請參閱<http://nuget.codeplex.com/workitem/4344>。


> > 升級到 MVC 5.2 解決了這個問題(可能是因為它沒有打更新檔,因此沒有註入 GAC);DLL 現在被複製到輸出文件夾。升級到 5.2.2 的差異沒有任何變化,除了版本號更改(特別是沒有添加/編輯節點)。 > > >

這是正確的。由於 MVC 5.2 不是 GAC 的,即使沒有顯式&lt;Private&gt;True&lt;/Private&gt;設置,這個非 GAC 程序集的預設值也會是 CopyLocal=true。


> > 我們不希望開始對所有內容進行 GAC,也不希望創建手動建構步驟來將我們所有的 DLL 複製到 bin 文件夾中,以防 MS 修補它們。那麼,如果 MS 將來修補其他 DLL,我們今天可以改變什麼來確保我們不會最終導致 BuildServer 默默地產生錯誤的建構? > > >

你今天能做的最好的事情是:

  1. &lt;Private&gt;True&lt;/Private&gt;為所有 NuGet 包程序集引用在 .csproj 文件中放置顯式設置。
  2. 在修復 NuGet 錯誤 #4344 之前,只要您使用 NuGet 更新包引用,請返回您的 .csproj 文件並重新添加顯式&lt;Private&gt;True&lt;/Private&gt;設置。

引用自:https://stackoverflow.com/questions/26467078