依赖DLL未被复制到Visual Studio中的生成输出文件夹

Bri*_*rij 175 .net c# dll reference visual-studio-2010

我有一个visual studio解决方案.我在解决方案中有很多项目.有一个主要项目作为启动并使用其他项目.有一个项目说"ProjectX".它的参考被添加到主项目中.ProjectX引用了另一个不是解决方案的.NET dll(例如abc.dll).

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

Ove*_*urg 102

我发现如果ProjectX引用了abc.dll但没有直接使用abc.dll中的任何DEFINED类型,则不会将abc.dll复制到主输出文件夹.(它将被复制到ProjectX输出文件夹,使其更加混乱.)

因此,如果你没有在ProjectX中的任何地方明确使用abc.dll中的任何类型,那么在ProjectX中的一个文件中的某处放置一个虚拟声明.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied
Run Code Online (Sandbox Code Playgroud)

您不需要为每个类执行此操作 - 只需一次就足以使DLL复制并且一切都按预期工作.

附录:请注意,这可能适用于调试模式,但不适用于发布.有关详细信息,请参阅@nvirth的答案.

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

nvi*_*rth 62

只是对霸王Zurg的回答的旁注.

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

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 在发布模式下,优化器假定未使用"虚拟",因此该行是不必要的,应该删除.但是当你在代码中使用"dummy"时,优化器并不认为它是不必要的. (5认同)
  • 确保`AbcDll.AnyClass`用作公共类的公共字段或属性,然后它将起作用.如果你在这样的方法体中使用它,编译器不会_see it_.它会延迟加载这个程序集,而不是你想要发生的事情. (3认同)
  • 这对我不起作用。AbcDll.AnyClass 仍然没有复制到其他项目 (2认同)

Mik*_*oud 49

是的,你需要设置Copy Localtrue.不过,我敢肯定,你还需要从主项目引用该组件,并设置Copy Localtrue以及-它不只是得到从依赖程序集复制.

您可以Copy Local通过单击下面的组件References并按F4 进入该属性.

  • @mcmillab,简而言之,Visual Studio不会**推断来自其他依赖项目的**依赖项.如果项目A引用项目B,项目A将需要具有项目B的所有引用.当所有项目B需要的是.NET程序集时,它运行良好,但如果它是第三方程序集,则必须添加对这两个项目的引用. (27认同)
  • @MichaelPerrenoud我不认为这是真的.如果查看详细的MSBuild输出,您将看到对[ResolveAssemblyReference](http://msdn.microsoft.com/en-us/library/9ad3f294.aspx)的调用,该调用声明它"包含第二个和第n个依赖项".这也与我在bin文件夹中看到的内容一致(第n个依赖项被复制).问题是有一些关于复制内容的警告,主要是围绕GAC和间接引用(Add Reference有时不够) (11认同)
  • @Brij,是你想要它的**主项目引用的程序集?正如我所说,**我很确定**你需要从该项目中引用 - 依赖程序集不会被复制.如果是这种情况,则在使用NuGet时不需要将程序集添加到所有相关项目中. (2认同)
  • 我目前的经验是,这将适用于*除了*“复制”依赖项:项目 A.net 将外部 C++ dll 引用为“始终复制”的文件。项目 B.net 引用项目 A。在构建时,B/Debug 包括 C++ dll。但是,当我构建引用项目 B 的应用程序 X 时,C++ dll *有时* 会被复制(似乎只有在我进行重建时才会复制)。 (2认同)
  • 我很确定这是*错误*。它不需要*推断依赖关系*,它只需要*复制输出*(从一个项目的bin到另一个项目的bin),MSBuild至少在正常情况下会这样做。 (2认同)

Ary*_*dlé 31

当您将其设置为装配属性时,它看起来很光滑

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法将是:

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]
Run Code Online (Sandbox Code Playgroud)


Dar*_*nso 23

进入同样的问题.背景信息:在构建之前,我在解决方案中添加了一个新的Project X. 项目Y依赖于项目X,项目A,B,C依赖于项目Y.

构建错误是找不到项目A,B,C,Y和X dll.

根本原因是新创建的Project X以.NET 4.5为目标,而其余解决方案项目则以.NET 4.5.1为目标. Project X没有构建,导致其他项目也没有构建.

确保所有新添加的项目都与解决方案的其余部分目标相同的.NET版本.


da_*_*ker 16

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

我通过"添加现有文件"在Visual Studio中完成此操作.除了Add_data文件夹之外,您应该可以将它添加到任何位置.我个人只是将它添加到根目录.

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

Build Action = None(将此设置为内容实际上将"root"版本复制到根目录,再加上Bin中的副本).

复制到输出文件夹=如果更新则复制(基本上只有在缺少时将其放入BIN文件夹,但之后不执行)

当我发布时...我添加的DLL仅存在于BIN文件夹中,而在发布位置中没有其他地方(这就是我想要的).


小智 10

您还可以检查以确保您要查找的DLL未包含在GAC中.我相信如果构建计算机上的GAC中已经存在这些文件,那么Visual Studio非常聪明.

我最近遇到过这种情况,我一直在测试一个需要在GAC中存在程序集的SSIS包.我已经忘记了这一点,并想知道为什么这些DLL在构建期间没有出现.

要检查GAC中的内容(从Visual Studio Developer命令提示符):

gacutil -l
Run Code Online (Sandbox Code Playgroud)

或者输出到文件以便于阅读:

gacutil -l > output.txt
notepad.exe output.txt
Run Code Online (Sandbox Code Playgroud)

要删除程序集:

gacutil -u MyProjectAssemblyName
Run Code Online (Sandbox Code Playgroud)

我还应该注意,一旦我从GAC中删除了文件,它们在构建后正确地输出到\ bin目录中(即使对于根项目中没有直接引用的程序集).这是在Visual Studio 2013 Update 5上.


Hoo*_*ini 8

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

在此输入图像描述