我有一个视觉工作室解决方案。我在解决方案中有很多项目。有一个主要项目作为启动并使用其他项目。有一个项目说“ProjectX”。它的引用被添加到主项目中。 ProjectX 引用了另一个不属于解决方案的 .NET dll(比如 abc.dll)。
现在这个 abc.dll 应该被复制到主项目的 bin/debug 文件夹,但它没有被复制到那里。为什么它没有被复制,任何已知的原因?
RestoreProjectStyle
solution available。想法是为解决方案中的每个 .Net Framework 项目设置 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
。
我发现如果 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 的答案。
只是对祖格大王的回答的一个旁注。
我以这种方式添加了虚拟引用,它在调试模式下工作:
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);
}
}
这个信息实际上花了我几个小时才弄清楚,所以我想我分享它。
AbcDll.AnyClass
用作公共类的公共字段或属性,然后它将起作用。如果你在这样的方法体中使用它,编译器不会看到它。它会延迟加载这个程序集,而不是你想要发生的事情。
是的,您需要将 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 中。我相信如果构建机器上的 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 上。
如果您右键单击引用的程序集,您将看到一个名为 Copy Local 的属性。如果 Copy Local 设置为 true,则程序集应包含在 bin 中。但是,Visual Studio 似乎存在问题,有时它不包含 bin 文件夹中引用的 dll ......这是对我有用的解决方法:
https://i.stack.imgur.com/yELFN.gif
就我而言,这是最愚蠢的事情,由我不同意的 TFS/VS 的默认行为引起。
由于添加 dll 作为对主项目的引用不起作用,我决定将其添加为“现有项目”,其中 Copy Local = Always。即使那样,该文件也不存在。
事实证明,即使文件存在于 VS 解决方案中并且所有内容都在本地和服务器上编译,VS/TFS 并没有实际添加文件到源代码管理。它根本不包含在“待定更改”中。我必须手动转到源代码管理资源管理器并明确单击“将项目添加到文件夹”图标。
愚蠢,因为我已经在 VS 中开发了 15 年。我以前遇到过这种情况,我只是不记得了,不知何故我错过了它,因为由于文件是常规引用,所有内容仍然编译,但是作为现有项目添加的文件没有被复制,因为它不存在源代码控制服务器。
我希望这可以节省一些时间,因为我为此失去了 2 天的生命。
gitignore
模式,因此在添加为引用时它没有添加到项目中。您必须手动将文件添加到源代码管理!!!
问题:
在构建输出不包含引用的 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/
确保您使用的依赖 DLL 的目标 .NET Framework 不高于项目应用程序的目标 .NET Framework。
您可以通过选择项目来检查这一点,然后按 ALT+ENTER,然后从左侧选择应用程序,然后选择项目的目标框架。
假设,依赖 DLL Target Framework = 4.0 和 Application DLL Target Framework = 3.5 然后将其更改为 4.0
谢谢!
这是对 nvirth 示例的轻微调整
internal class DummyClass
{
private static void Dummy()
{
Noop(typeof(AbcDll.AnyClass));
}
private static void Noop(Type _) { }
}
我会将它添加到 Postbuild 事件中,以将必要的库复制到输出目录。像 XCopy pathtolibraries targetdirectory 这样的东西
您可以在项目属性 -> 构建事件中找到它们。
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 分钟的生产力损失 :-)
代码中不需要假人:
添加对可执行项目的引用
或/并确保可执行项目中的引用已将 "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 的一个愚蠢问题。
感谢所有其他帮助我了解原因的答案。
高温高压
我有一个类似的问题,其中我作为内容包含在项目中的 DLL 和“始终复制”设置没有被复制到 bin 文件夹中。我通过在 app.config 中添加对 DLL 的dependentAssembly 引用解决了这个问题。