2010-06-23 71 views
26

我可以在Visual Studio中將「複製本地」的默認選項設置爲False嗎?在大多數情況下,當我添加一個dll作爲項目的依賴項時,我想將Copy Local屬性設置爲False。默認情況下,它是True。有沒有辦法改變Visual Studio的默認行爲? (2008)默認情況下將「Copy Local」設置爲False?

回答

32

否 - Visual Studio使用一組內部規則來確定要將Copy Local設置爲的內容。

MSDN

  1. 如果引用另一個項目,稱爲項目到項目的引用,則該值爲
  2. 如果在全局程序集緩存中找到程序集,則值爲false
  3. 作爲特例,mscorlib.dll參考值爲false
  4. 如果程序集位於Framework SDK文件夾中,則值爲false
  5. 否則,值爲true
23

其實,你可以。你需要幾件事情:

  1. 創建.targets文件,使copylocal(<Private>標籤,要準確)false by default
  2. 導入.csproj文件中的目標。您可以在關閉</Project>標籤之前將其添加到最後一行,它會看起來像<Import Project="..\Build\yourtarget.targets" />

現在,每個包含此目標的項目都默認禁用copylocal。

缺點是你需要修改每一個csproj文件,包括新的。您可以通過modifying the VS project template解決新項目問題。在博客文章中描述的Class.cs而不是Class.cs,您需要修改Class.vstemplate(在同一個zip文件中)。

用這種方法,還有一個問題 - 路徑本身。如果你在新生成的csproj文件中使用硬編碼的相對路徑,它們可能是錯誤的(除非你有平坦的項目結構)。

您可以:

  • 讓VS生成正確的相對路徑。不知道如何做到這一點,如果這是可能的。
  • 忽略它併爲每個新的csproj手動更改路徑(取決於您擁有的新項目的數量,雖然不理想,這可能是可以接受的)。
  • 使用環境變量而不是相對路徑。在這種情況下,每個開發人員都需要相同的變量集。

必須有更好的解決方案,但還沒有找到它。

+0

這似乎是正確的答案,我已經試過了指導和鏈接和它的作品! – 2012-08-01 21:24:39

+0

@AnthonyMastrean:你想出了一個巧妙的方式把進口在一個新創建的csproj文件? – ya23 2012-09-05 13:27:56

+0

我們正在玩一個通用的'.csproj'文件,該文件通過使用模板導入到每個新項目中。模板系統不是很乾淨,我們不確定我們是否喜歡它。 – 2012-09-05 14:58:45

5

碰碰這個,因爲它似乎現在有一個NuGet包正是這一點使...

https://nuget.org/packages/CopyLocalFalse

沒有嘗試過呢,只是希望它幫助。

+0

有了這個nuget包,沒有保證。在安裝腳本中有一些預定義的過濾,它會跳過一些引用,並且只在nuget包的安裝時才運行,nuget包可能已經安裝並且添加了一個新的引用,同樣如果nuget包被恢復在其他軟件包恢復之前,哪些其他軟件包可能會重置其引用程序集的本地拷貝?不推薦使用此方法。更好地使用目標來覆蓋本地拷貝並擁有自己的fi濾波。 – vezenkov 2015-06-30 06:43:01

3

我們不使用.targets文件(如在由ya23答案的建議),所以我們只是在文本編輯器手動編輯.csproj項目文件和<Private>元素添加到引用,就像這樣:

<Reference Include="[...]"> 
    <Private>False</Private> 
    [...] 
</Reference> 

<Private>元素的值與「Copy local」屬性的值匹配。例如,如果<Private>設置爲False,則「本地複製」也爲false。

0

關於@herzbube發佈的解決方案,如果您要關閉「複製本地」以覆蓋全部(或大部分)在.csproj的文件引用,你不需要單獨設置<Private>False</Private>每個Reference,你可以把直接在的.csproj如下:

<ItemDefinitionGroup> 
    <Reference> 
    <Private>False</Private> 
    </Reference> 
</ItemDefinitionGroup> 

這並不影響引用的項目與<ProjectReference>,但你可以做同樣的事情 - 或者代替也可以 - 第OSE:

<ItemDefinitionGroup> 
    <ProjectReference> 
    <Private>False</Private> 
    </ProjectReference> 
</ItemDefinitionGroup> 

如果你想這兩個,你可以將它們合併成一個組:

<ItemDefinitionGroup> 
    <Reference> 
    <Private>False</Private> 
    </Reference> 
    <ProjectReference> 
    <Private>False</Private> 
    </ProjectReference> 
</ItemDefinitionGroup> 

確保你把這些覆蓋第一實際<Reference ...><ProjectReference ...>要影響之前因爲這些塊只適用於那些出現在它們下面的引用。然後,如果有幾件你真的想在本地複製,那麼你可以單獨地(即,在單個標籤本身內)覆蓋那些,這次使用True

對於更高級的情況下,你可以在同一個.csproj的文件切換壓倒一切的價值來回多次之間。另一種先進的技術是戰略性地將一些引用放置在這些塊的下面,以及上面的其他引用,所以後者不會受到影響。

所有這些都會使您的.csproj中的XML更清晰易讀。但是,還有更多的好消息,讓閱讀...


至於選擇哪些項目應該被標記<Private>False</Private>這通常將取決於具體情況,但有一些基本的東西大家可以應爲首發。這是一個如此基本,簡單而有效的步驟,它提供如此巨大的MSBuild可靠性改進1。和構建時加速 - 與小缺點 - 這是使用默認值(即每個項目的地方),每一個大的解決方案C#輸出位置應該總是做這樣的調整:

在任何和每一個Visual Studio解決方案,其建立多個C#類庫與任何非平凡數的<ProjectReference>相互依賴性,並且其高潮在建立一個更應用(即可執行文件):

  1. 靠近頂端的.csproj每類庫,插入<ProjectReference>塊如上所示。
    原因:有沒有必要進行任何.DLL收集任何它引用到自己的子目錄庫的,因爲沒有可執行的是不斷從該位置運行。這種猖獗的複製是無用的忙碌,可能會不必要地拖慢你的構建,可能相當戲劇性。

  2. 在另一方面,做修改的.csproj爲自己的任何解決方案的應用
    原因:可執行文件需要得到他們在各自的子目錄需要私人建庫,但建立單獨的每個應用程序應負責分別從各自的子目錄收集每一個依賴,直接進入應用程序的子目錄。

這工作完全是因爲對.csproj的類庫引用多個其他類庫,但是對於一個可執行的.csproj平時從不引用另一個可執行文件。因此,對於每一個本地建庫,在其bin文件夾中的唯一.DLL會本身,而每一個本地構建的應用程序將包含全套它引用本地建庫。

方便的是,沒有任何更改的參考庫不是由您的解決方案構建的,因爲它們通常使用<Reference>而不是<ProjectReference>,並且我們根本沒有修改以前的標籤。但請注意剛纔提到的假設;如果您的某些項目違反了該規定,則可能需要進行一些調整。

可靠性改進可能與從依賴圖中的多個不相交路徑收集同一個庫時可能發生的文件衝突有關,尤其是在併發構建中。

相關問題