簡體   English   中英

從屬 DLL 未被復制到 Visual Studio 中的構建 output 文件夾

[英]Dependent DLL is not getting copied to the build output folder in Visual Studio

我有一個視覺工作室解決方案。 我在解決方案中有很多項目。 有一個主要項目作為啟動並使用其他項目。 有一個項目說“ProjectX”。 它的引用被添加到主項目中。 ProjectX 引用了另一個 .NET dll(比如 abc.dll),它不是解決方案的一部分。

現在這個 abc.dll 應該被復制到主項目的 bin/debug 文件夾,但它沒有被復制到那里。 為什么它沒有被復制,任何已知的原因?

我發現如果 ProjectX 引用了 abc.dll 但沒有直接使用 abc.dll 中定義的任何類型,那么 abc.dll 將不會被復制到主輸出文件夾。 (它將被復制到 ProjectX 輸出文件夾中,使其更加混亂。)

因此,如果您沒有在 ProjectX 中的任何位置顯式使用 abc.dll 中的任何類型,請在 ProjectX 中的一個文件中的某處放置一個虛擬聲明。

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

您不需要對每個類都這樣做——只需一次就足以使 DLL 副本和一切按預期工作。

附錄:請注意,這可能適用於調試模式,但不適用於發布。 有關詳細信息,請參閱@nvirth 的回答。

只是 Zurg 大王回答的旁注。

我以這種方式添加了虛擬引用,它在調試模式下工作:

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

但是在 Release 模式下,依賴的 dll 仍然沒有被復制。
然而,這有效:

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

這些信息實際上花了我幾個小時來弄清楚,所以我想我分享一下。

是的,您需要將Copy Local設置為true 但是,我很確定您還需要從主項目中引用該程序集並將Copy Local設置為true - 它不僅僅是從依賴程序集復制。

您可以通過單擊“ References下的組件並按 F4 來訪問“ Copy Local屬性。

當您將其設置為程序集屬性時,它看起來很光滑

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

用法將是:

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

遇到了同樣的問題。 背景信息:在構建之前,我在解決方案中添加了一個新的 Project X。 項目 Y 依賴於項目 X,項目 A、B、C 依賴於項目 Y。

構建錯誤是無法找到項目 A、B、C、Y 和 X dll。

根本原因是新創建的 Project X 以 .NET 4.5 為目標,而其余解決方案項目以 .NET 4.5.1 為目標。 項目 X 未構建導致其余項目也未構建。

確保任何新添加的項目都針對與解決方案其余部分相同的 .NET 版本。

不確定這是否有幫助,但對我來說,很多時候我引用了一個 DLL(當然它會自動將它添加到 bin 文件夾中)。 但是,該 DLL 可能需要額外的 DLL(取決於我使用的函數)。 我不想在我的項目中引用它們,因為它們只需要與我實際使用的 DLL 位於同一文件夾中。

我通過“添加現有文件”在 Visual Studio 中完成此操作。 您應該能夠將它添加到除 Add_data 文件夾之外的任何地方。 我個人只是將它添加到根目錄。

然后將該文件的屬性更改為...

Build Action = None(將此設置為類似 Content 的內容實際上會將“root”版本復制到根目錄,以及 Bin 中的副本)。

復制到輸出文件夾 = 如果較新則復制(基本上只有在它丟失時才將其放入 BIN 文件夾中,但之后不會這樣做)

當我發布時..我添加的 DLL 只存在於 BIN 文件夾中,而在發布位置(這是我想要的)中沒有其他地方。

您還可以檢查以確保您要查找的 DLL 未包含在 GAC 中。 我相信如果 Visual Studio 已經存在於構建機器上的 GAC 中,則不會復制這些文件是明智的。

我最近遇到過這種情況,我一直在測試一個需要在 GAC 中存在程序集的 SSIS 包。 我已經忘記了這一點,並想知道為什么這些 DLL 在構建過程中沒有出現。

要檢查 GAC 中的內容(從 Visual Studio 開發人員命令提示符):

gacutil -l

或輸出到文件以使其更易於閱讀:

gacutil -l > output.txt
notepad.exe output.txt

要移除裝配體:

gacutil -u MyProjectAssemblyName

我還應該注意,一旦我從 GAC 中刪除了文件,它們就會在構建后正確輸出到 \\bin 目錄中(即使對於在根項目中沒有直接引用的程序集)。 這是在 Visual Studio 2013 Update 5 上。

如果右鍵單擊引用的程序集,您將看到一個名為Copy Local的屬性。 如果 Copy Local 設置為 true,則程序集應包含在 bin 中。 但是,Visual Studio 存在接縫問題,有時它在 bin 文件夾中不包含引用的 dll...這是對我有用的解決方法:

在此處輸入圖片說明

就我而言,這是最愚蠢的事情,由我不同意的 TFS/VS 的默認行為引起。

由於將 dll 添加為對主項目的引用不起作用,因此我決定將其添加為“現有項目”,並使用 Copy Local = Always。 即使那時文件也不在那里。

事實證明,即使該文件存在於 VS 解決方案中並且所有內容都在本地和服務器上編譯,VS/TFS 並沒有將文件添加到源代碼管理中。 它根本不包括在“待定更改”中。 我必須手動轉到源代碼管理資源管理器並明確單擊“將項目添加到文件夾”圖標。

愚蠢,因為我已經在 VS 中開發了 15 年。 我以前遇到過這個,我只是不記得了,不知何故我錯過了它,因為由於文件是常規引用,所有內容仍然編譯,但是作為現有項目添加的文件沒有被復制,因為它不存在於源代碼控制服務器。

我希望這可以節省一些時間,因為我為此失去了 2 天的生命。

這是對 nvirth 示例的輕微調整

internal class DummyClass
{
    private static void Dummy()
    {
        Noop(typeof(AbcDll.AnyClass));
    }
    private static void Noop(Type _) { }
}

我會將它添加到 Postbuild 事件以將必要的庫復制到輸出目錄。 像 XCopy pathtolibraries targetdirectory 之類的東西

您可以在項目屬性 -> 構建事件中找到它們。

問題:

遇到 NuGet 包 DLL (Newtonsoft.json.dll) 的類似問題,其中構建輸出不包含引用的 DLL。 但是編譯進行得很好。

使固定:

在文本編輯器中瀏覽您的項目,並在其中查找帶有“私人”標簽的引用。 像真或假。 “私人”是“復制本地”的同義詞。 在操作中的某個地方,MSBuild 正在定位依賴項,它會在其他地方找到您的依賴項並決定不復制它。

因此,瀏覽每個 .csproj/.vbproj 文件並手動刪除標簽。 重建,一切都在 Visual Studio 和 MSBuild 中工作。 一旦你開始工作,你就可以返回並更新到你認為他們需要的地方。

參考:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/

TLDR; Visual Studio 2019 可能只需要重新啟動。

我在使用基於 Microsoft.NET.Sdk 項目的項目時遇到了這種情況。

<Project Sdk="Microsoft.NET.Sdk">

具體來說:

  • Project1 :目標.netstandard2.1
    • 通過 Nuget 引用Microsoft.Extensions.Logging.Console
  • Project2 :目標.netstandard2.1
    • 通過項目引用引用Project1
  • Project2Tests :目標.netcoreapp3.1
    • 通過項目引用引用Project2

在測試執行時,我收到錯誤消息,指出找不到Microsoft.Extensions.Logging.Console ,並且它確實不在輸出目錄中。

我決定通過將Microsoft.Extensions.Logging.Console添加到Project2來解決這個問題,結果發現 Visual Studio 的 Nuget Manager 沒有列出Microsoft.Extensions.Logging.Console安裝在Project1 ,盡管它存在於Project1.csproj文件。

簡單地關閉並重新啟動 Visual Studio 即可解決該問題,而無需添加額外的引用。 也許這會為某人節省 45 分鍾的生產力損失:-)

確保您使用的依賴 DLL 的目標 .NET Framework 不高於項目應用程序的目標 .NET Framework。

您可以通過選擇您的項目來檢查這一點,然后按ALT + ENTER ,然后從左側選擇應用程序,然后選擇項目的目標框架。

假設,依賴 DLL 目標框架 = 4.0 和應用程序 DLL 目標框架 = 3.5 然后將其更改為 4.0

謝謝!

不需要代碼中的虛擬
只是 :

添加對可執行項目的引用

或/並確保可執行項目中的引用將"Copy Local"設置為TRUE (這是我的“錯誤”)似乎這“覆蓋”了基本引用庫項目中的設置...

您可以將主項目和 ProjectX 的構建輸出路徑設置為同一個文件夾,然后您就可以在該文件夾中獲取您需要的所有 dll。

除了上面的常見解決方案之外,我還有一個多項目解決方案要發布。 顯然有些文件針對不同的框架。

所以我的解決方案:屬性>特定版本(錯誤)

將 DLL 作為現有項目添加到項目之一,並應對其進行排序

VS2019 V16.6.3

對我來說,問題是不知何故,主 .proj 文件以這樣的條目結束,該項目的 DLL 沒有被復制到父項目 bin 文件夾:

<ProjectReference Include="Project B.csproj">
  <Project>{blah blah}</Project>
  <Name>Project B</Name>
  <Private>True</Private>
</ProjectReference>

我手動刪除了<Private>True</Private> ,然后在每次構建主項目時將 DLL 復制到主項目 bin 文件夾中。

如果您轉到主項目的引用文件夾中問題項目的引用,單擊它並查看屬性,有一個“復制本地”設置。 私有標記等同於此設置,但對我而言,出於某種原因更改復制本地對 .proj 文件中的私有標記沒有影響。

令人討厭的是,我沒有更改引用的復制本地值,不知道它是如何設置的,又浪費了一天來追蹤 VS 的一個愚蠢問題。

感謝所有其他幫助我了解原因的答案。

HTH

我有一個類似的問題,其中我作為內容包含在項目中的 DLL 和“始終復制”設置沒有被復制到 bin 文件夾。 我通過在 app.config 中添加對 DLL 的 dependentAssembly 引用解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM