ChatGPT解决这个技术问题 Extra ChatGPT

从属 DLL 未复制到 Visual Studio 中的生成输出文件夹

我有一个视觉工作室解决方案。我在解决方案中有很多项目。有一个主要项目作为启动并使用其他项目。有一个项目说“ProjectX”。它的引用被添加到主项目中。 ProjectX 引用了另一个不属于解决方案的 .NET dll(比如 abc.dll)。

现在这个 abc.dll 应该被复制到主项目的 bin/debug 文件夹,但它没有被复制到那里。为什么它没有被复制,任何已知的原因?

如果您无法弄清楚这一点,请将其复制到您的预构建中。
你如何在主项目中使用你的“ProjectX”——项目的类型、目标等是什么?
我有同样的问题,这个答案解决了我的问题:stackoverflow.com/a/8213977/174469
RestoreProjectStyle solution available。想法是为解决方案中的每个 .Net Framework 项目设置 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>

O
Overlord Zurg

我发现如果 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 的答案。


这似乎是一个黑客。添加对主项目的引用似乎就足够了。
这是一个 hack,但正如今天的 CodeProject 新闻告诉我们的那样,即使是编译器也可能出错!
事情有多疯狂。 @OverlordZurg您的解决方案有效,因为我在我的XAML(WPF)中引用了依赖dll,并且它没有将DLL复制到主项目,直到我按照您所说的添加一个简单的虚拟引用......无论如何谢谢
@MohsenAfshin 我有同样的问题---我在 XAML 中引用了一个依赖 DLL。然而,我没有声明一个虚拟变量,而是简单地命名了我在 XAML 中使用的组件,这足以导致其程序集被复制。
@MikeK 将它添加到主项目(实际上并不直接依赖它)是一个更大的黑客,imo。然后你必须在两个地方管理它(“管理”,如升级或删除)。有了这个hack,至少你会得到一个很好的编译时错误,提醒你在删除依赖项时删除这个hack,你仍然只需要在一个地方更新它。
n
nvirth

只是对祖格大王的回答的一个旁注。

我以这种方式添加了虚拟引用,它在调试模式下工作:

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

但是在发布模式下,依赖的 dll 仍然没有被复制。然而,这有效:

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

这个信息实际上花了我几个小时才弄清楚,所以我想我分享它。


在发布模式下,优化器假定“dummy”没有被使用,所以这条线是不必要的,应该被删除。但是当你在代码中使用“dummy”时,优化器不会认为这是不必要的。
这对我不起作用。AbcDll.AnyClass 仍然没有复制到其他项目
确保 AbcDll.AnyClass 用作公共类的公共字段或属性,然后它将起作用。如果你在这样的方法体中使用它,编译器不会看到它。它会延迟加载这个程序集,而不是你想要发生的事情。
M
Mike Perrenoud

是的,您需要将 Copy Local 设置为 true。但是,我很确定您还需要从主项目中引用该程序集并将 Copy Local 设置为 true - 它不仅仅是从依赖程序集中复制的.

您可以通过单击 References 下的程序集并按 F4 来访问 Copy Local 属性。


@Brij,该程序集是从您想要的主项目中引用的吗?正如我所说,我很确定您也需要从该项目中引用 - 依赖程序集不会像那样复制。如果是这种情况,您在使用 NuGet 时不需要将程序集添加到所有相关项目。
@mcmillab,简而言之,Visual Studio 不会从其他依赖项目中推断出依赖关系。如果项目 A 引用项目 B,则项目 A 需要拥有项目 B 的所有引用。当所有项目 B 需要的是 .NET 程序集时,它工作得很好,但如果它是第 3 方程序集,则必须添加对两个项目的引用。
@MichaelPerrenoud 我认为这不是真的。如果您查看详细的 MSBuild 输出,您将看到对 ResolveAssemblyReference 的调用,其中指出它“包括二阶和 n 阶依赖项”。这也与我在 bin 文件夹中看到的一致(第 n 个依赖项被复制)。问题是对复制的内容有一些警告,主要是围绕 GAC 和间接引用(添加引用有时还不够)
我目前的经验是,除了“复制”依赖项之外,这将起作用:项目 A.net 将外部 C++ dll 引用为“始终复制”的文件。项目 B.net 引用项目 A。在构建时,B/Debug 包括 C++ dll。但是,当我构建引用项目 B 的应用程序 X 时,C++ dll 有时会被复制(似乎只有在我进行重建时才会复制)。
我很确定这是错误的。它不需要推断依赖关系,它只需要复制输出(从一个项目的 bin 到另一个项目的 bin),这是 MSBuild 所做的,至少通常是这样。
A
Aryéh Radlé

当您将其设置为程序集属性时,它看起来很漂亮

[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))]

谢谢,但对我来说,这只在我将程序集属性添加到已经引用 AbcDll.AnyClass 的依赖项(项目 X)时才起作用。然后,它不会做更多的事情,它将 AbcDll 复制到依赖项的输出目录。它仍然不会将其复制到主要依赖项目的输出中。除非我还添加对 AbcDll 的引用,否则我无法将该属性添加到依赖程序集。当我这样做时,AbcDll 已经在没有属性的情况下被复制了。
D
Darren Alfonso

遇到同样的问题。背景信息:在构建之前,我在解决方案中添加了一个新的 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 版本为目标。


引用的项目可能是 .NET 的旧版本。我可以通过为 .NET 4.5 构建的项目引用为 .NET 4 构建的项目。
d
da_jokker

不确定这是否有帮助,但对我来说,很多时候我引用了一个 DLL(当然,它会自动将它添加到 bin 文件夹中)。但是,该 DLL 可能需要额外的 DLL(取决于我使用的函数)。我不想在我的项目中引用它们,因为它们只需要与我实际使用的 DLL 在同一个文件夹中结束。

我通过“添加现有文件”在 Visual Studio 中完成此操作。您应该能够将它添加到除 Add_data 文件夹之外的任何位置。我个人只是将它添加到根目录。

然后将该文件的属性更改为...

Build Action = None(将此设置为 Content 实际上会将“root”版本复制到根目录,以及 Bin 中的副本)。

复制到输出文件夹 = 如果较新则复制(基本上只有在丢失时才将其放入 BIN 文件夹,但之后不会这样做)

当我发布时..我添加的 DLL 仅存在于 BIN 文件夹中,而在发布位置(这是我想要的)中不存在。


B
Brett

您还可以检查以确保您要查找的 DLL 不包含在 GAC 中。我相信如果构建机器上的 GAC 中已经存在这些文件,Visual Studio 会很聪明地不复制这些文件。

我最近遇到了这种情况,我一直在测试一个需要在 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 上。


谢谢,你是对的,如果 MSBuild 在 GAC 中找到它们,它不会将 dll 复制到输出文件夹。
H
Hooman Bahreini

如果您右键单击引用的程序集,您将看到一个名为 Copy Local 的属性。如果 Copy Local 设置为 true,则程序集应包含在 bin 中。但是,Visual Studio 似乎存在问题,有时它不包含 bin 文件夹中引用的 dll ......这是对我有用的解决方法:

https://i.stack.imgur.com/yELFN.gif


复制 Loal 已禁用,这有助于 stackoverflow.com/questions/15526491/…
G
GR7

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

由于添加 dll 作为对主项目的引用不起作用,我决定将其添加为“现有项目”,其中 Copy Local = Always。即使那样,该文件也不存在。

事实证明,即使文件存在于 VS 解决方案中并且所有内容都在本地和服务器上编译,VS/TFS 并没有实际添加文件到源代码管理。它根本不包含在“待定更改”中。我必须手动转到源代码管理资源管理器并明确单击“将项目添加到文件夹”图标。

愚蠢,因为我已经在 VS 中开发了 15 年。我以前遇到过这种情况,我只是不记得了,不知何故我错过了它,因为由于文件是常规引用,所有内容仍然编译,但是作为现有项目添加的文件没有被复制,因为它不存在源代码控制服务器。

我希望这可以节省一些时间,因为我为此失去了 2 天的生命。


我不能感谢你...你为我节省了很多时间。这对我来说是解决方案。它还暴露了根本问题,我作为引用添加的 DLL 匹配 gitignore 模式,因此在添加为引用时它没有添加到项目中。您必须手动将文件添加到源代码管理!!!
A
Ambrose Leung

问题:

在构建输出不包含引用的 DLL 的 NuGet 包 DLL (Newtonsoft.json.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/


R
RBT

确保您使用的依赖 DLL 的目标 .NET Framework 不高于项目应用程序的目标 .NET Framework。

您可以通过选择项目来检查这一点,然后按 ALT+ENTER,然后从左侧选择应用程序,然后选择项目的目标框架。

假设,依赖 DLL Target Framework = 4.0 和 Application DLL Target Framework = 3.5 然后将其更改为 4.0

谢谢!


m
maca134

这是对 nvirth 示例的轻微调整

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

c
chethan jain

我会将它添加到 Postbuild 事件中,以将必要的库复制到输出目录。像 XCopy pathtolibraries targetdirectory 这样的东西

您可以在项目属性 -> 构建事件中找到它们。


这对我有用,我认为这是更好的答案。虚拟参考解决方案有效,但它是一种 hack,而构建后规则是实现相同结果的一种干净方式。
E
Eric Patrick

TLDR; Visual Studio 2019 可能只需要重新启动。

我在使用基于 Microsoft.NET.Sdk 项目的项目时遇到了这种情况。

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

具体来说:

Project1:目标 .netstandard2.1 通过 Nuget 引用 Microsoft.Extensions.Logging.Console

通过 Nuget 引用 Microsoft.Extensions.Logging.Console

Project2:目标 .netstandard2.1 通过项目引用引用 Project1

通过项目引用引用 Project1

Project2Tests:目标 .netcoreapp3.1 通过项目引用引用 Project2

通过项目引用引用 Project2

在测试执行时,我收到错误消息,指出找不到 Microsoft.Extensions.Logging.Console,并且它确实 不在 输出目录中。

我决定通过将 Microsoft.Extensions.Logging.Console 添加到 Project2 来解决此问题,但发现 Visual Studio 的 Nuget 管理器并未将 Microsoft.Extensions.Logging.Console 列为安装在 Project1 中,尽管它存在于 Project1.csproj 文件中。

简单地关闭并重新启动 Visual Studio 即可解决问题,无需添加额外的参考。也许这可以为某人节省 45 分钟的生产力损失 :-)


实际上,我在测试事物的过程中重新启动了整个 PC,但它对我有用
我对 SDK 项目 .NET5 有同样的问题,我尝试了这个解决方案,但不幸的是它对我不起作用,即使重新启动 PC :(
C
Cadburry

代码中不需要假人:

添加对可执行项目的引用

或/并确保可执行项目中的引用已将 "Copy Local" 设置为 TRUE(这是我的“错误”)似乎这个 “覆盖”在基础引用的库项目中设置...


Y
YantingChen

您可以将主项目和 ProjectX 的构建输出路径设置为同一个文件夹,然后您可以在该文件夹中获取您需要的所有 dll。


R
RicL

除了上面常见的之外,我还有一个多项目解决方案要发布。显然有些文件针对不同的框架。

所以我的解决方案:属性>特定版本(假)


a
abhijithkarkal

将 DLL 作为现有项目添加到其中一个项目中,并且应该对其进行排序


R
Richard Moore

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 的一个愚蠢问题。

感谢所有其他帮助我了解原因的答案。

高温高压


C
Coder

我有一个类似的问题,其中我作为内容包含在项目中的 DLL 和“始终复制”设置没有被复制到 bin 文件夹中。我通过在 app.config 中添加对 DLL 的dependentAssembly 引用解决了这个问题。