引用 DLL 文件未与部署项目一起复制到 bin,导致错误

Posted

技术标签:

【中文标题】引用 DLL 文件未与部署项目一起复制到 bin,导致错误【英文标题】:Reference DLL file not copying to bin with deployment project, causing error 【发布时间】:2011-02-26 04:23:15 【问题描述】:

我们的 Web 应用程序项目中引用了几个外部 DLL 文件。我们有一个用于在托管服务器上安装的部署项目。当我们使用 .NET 3.5 和 Visual Studio 2008 时,DLL 文件被复制到 bin 文件夹中。由于我们已升级到 .NET 4 和 Visual Studio 2010,这种情况不再发生,并且由于找不到引用,我们收到了服务器错误。

CopyLocal 设置为 true,我在 web.config 中找不到任何内容,这表明这是在其他地方设置的。

【问题讨论】:

可能与:Msbuild doesn’t copy references (dlls) if using project dependencies in solution 【参考方案1】:

Visual Studio 2010 中存在一个错误。默认情况下,解决方案文件中的 XML 如下所示:

<Reference Include="DevExpress.SpellChecker.v11.1.Core,
           Version=11.1.5.0,
           Culture=neutral,
           PublicKeyToken=b88d1754d700e49a,
           processorArchitecture=MSIL">
<HintPath>..\References\DevExpress.SpellChecker.v11.1.Core.dll</HintPath>
</Reference>

而 MSBuild 期望在下面这样做,因此 DLL 文件将包含在部署中:

<Reference Include="DevExpress.SpellChecker.v11.1.Core,
           Version=11.1.5.0,
           Culture=neutral,
           PublicKeyToken=b88d1754d700e49a,
           processorArchitecture=MSIL">
<HintPath>..\References\DevExpress.SpellChecker.v11.1.Core.dll</HintPath>
<Private>True</Private>
</Reference>

诀窍是将Copy Local 设置为False保存项目,然后将其重置为True - 再次保存。这包括正确的私有节点,MSBuild 尊重。

似乎 Visual Studio 2010 中不包含专用节点 (Copy Local) 的默认值是 True,而 MSBuild 将缺少的节点读取为 False

【讨论】:

在 VS2012 中仍然存在错误。确实应该修复,花了我一段时间才找到这个解决方案。 今天发现这个 CopyLocal 技巧不会影响当前项目上面的引用。例如,我有一个在 GAC 中引用 some.dll 的项目实体。如果我如上所述对 some.dll 强制 CopyLocal=true,一切似乎都很好 - some.dll 被复制到实体的 bin 文件夹中。但是,如果我在某些项目 Services 中引用 Entities 项目并希望将 some.dll 复制到 Services\bin,则不会发生 - Services 项目忽略了 Entities 项目的 CopyLocal=true 并仍然从广汽。使用 VS2012。 虽然这修复了项目文件,但 MSBuild.exe 从命令行仍然不遵守此设置,因此任何类型的自动构建脚本都不会正确构建代码(例如引用的项目引用 dll不会在 bin 目录中) 当我配置 nuGet 以提供缺少的包时,我遇到了 VS2013。我发现成功解决此问题的唯一方法是将对缺少的程序集的引用添加到我的起始项目中。耶奇。 我刚刚在 VS2015 中遇到了同样的问题。仅供参考,此答案中提到的 XML 引用存储在项目文件中,而不是解决方案文件中。【参考方案2】:

我遇到了同样的问题,我没有添加“BeforeBuild”步骤,而是创建了一个简单的测试

    [TestMethod]
    public void ReferenceAssemblyThatDoesNotCopyToBuildFolder()
    
        Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler referenceThisButDoNotUseIt = null;
    

这修复了错误类型“Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler...”无法解决

【讨论】:

【参考方案3】:

我的部署项目发生了一些奇怪的事情。当我看到它没有检测到依赖项时,我删除了主要输出并重新添加了它。

现在会显示依赖项,并在安装时将其放置在 bin 文件夹中。

【讨论】:

太棒了。只有一个问题:您是如何发现它没有检测到依赖关系的?这是哪个选项?请详细说明。谢谢 在我的部署项目中有一个检测到的依赖文件夹。它在那里检测到的唯一东西是 .net 框架。您可以右键单击此文件夹并单击“刷新依赖项”,但即使这对我也不起作用。当我重新添加主要输出时,检测到依赖关系。这很奇怪,是在 vs2008 和 vs2010 之间的转换过程中造成的。我会说这是一个错误,但事实上我所有的其他部署项目都完美地转换了。在一天结束时,我不知道发生了什么。 我在 vs.net 2010 中新创建的解决方案遇到了同样的问题,所以这不是升级问题。正如您所说,删除主要输出和读取似乎可以解决问题。 有人能澄清一下“删除主要输出”是什么意思吗? 他可能是这个意思:image.prntscr.com/image/1769f5e6958c4f89a865ed35d5e92224.png【参考方案4】:

我刚遇到同样的问题,想分享我的发现,因为它可能对某人有所帮助:

在我的情况下,原因是在安装某些第三方应用程序期间将程序集安装在 GAC 中。

如果 DLL 文件在 GAC 中,编译器不会费心将其复制到目标文件夹,除非您使用 Junto 提到的项目文件中的“私有”节点将其专门标记为“复制本地” .

问题是,如果你不添加那个节点,你在一台机器上开发并在另一台机器上构建,而DLL文件只在构建机器的GAC中,没有私有节点的默认行为将导致文件在开发机器上被正确复制,而不是在构建机器上。

更大的问题是,如果没有直接引用 DLL 文件,但项目引用了第二个项目,而该项目又引用了 DLL 文件。在这种情况下,您不能在项目中将 DLL 文件标记为“本地复制”,因为它没有被它引用。因此,如果 DLL 文件存在于 GAC 中 - 它不会被复制到您的输出文件夹中。

这种情况的可能解决方案是:

从 GAC 卸载 DLL 文件 在最终项目中添加对 DLL 文件的直接引用 使用新的强名称重新签署 DLL 文件,这将使其与 GAC 中的 DLL 文件区分开来。

【讨论】:

【参考方案5】:

我遇到了完全相同的问题。我们有一个引用 EnterpriseLibrary 的 Visual Studio 2008 项目。当我们使用 TFS 和我们的 Web 部署项目运行我们的集成构建时,所有的 DLL 文件都会被复制过来。当我们升级到 Visual Studio 2010、TFS 2010 和 WDP 2010 时,一些 DLL 文件丢失了。奇怪的是,这种情况只发生在某些 DLL 文件上,而其他的则不会。

例如,我们在两种情况下都复制了 Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll,但没有复制 Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll。

作为一种解决方法,我使用“BeforeBuild”步骤复制了文件。

现在看来可以构建了。

【讨论】:

【参考方案6】:

我没有遇到同样的问题,但类似。我有 WPF 主项目和引用的项目,其中引用的项目没有复制。我发现在我的情况下,主项目是为 NET 4.0 客户端配置文件设置的,并且为 NET 3.5 引用。当我将主项目设置为 3.5 时,引用项目的已编译 dll 开始复制。 (我不知道为什么,因为我通过实践解决了它)

【讨论】:

【参考方案7】:

我也遇到了类似的问题,即引用的 dll 未复制到已发布文件夹的 bin 中。我使用的是 TFS 签出副本,该副本未将 bin 文件夹包含到应用程序中。 -> 所以只包含 bin 文件夹。 -> 构建引用的应用程序 -> 发布网站项目 现在我在已发布文件夹中的 bin 中看到所有引用的 dll

【讨论】:

【参考方案8】:

我在使用 VS 2012 Express 时遇到了类似的问题。我在我的项目中使用了 Tesseract 库。在我将这个项目用于多个项目的解决方案之前,一切都运行良好。问题是一些通常放置在文件夹 bin/debug/x86 或 bin/debug/x64 中的 DLL(liblept168.dll、libtesseract302.dll)仅在我重建整个解决方案时才被复制。 更改一行并重新构建它会导致 DLL 被删除而不是复制回来。

我通过将创建缺失 DLL 的项目引用添加到启动项目来解决了这个问题。

【讨论】:

【参考方案9】:

rzen 和其他人,谢谢 - 您的 cmets 为我们找到了解决方案。

我们有一个针对 Microsoft.ReportViewer.Common.dll 和 Microsoft.ReportViewer.WebForms.dll 程序集(我们在“src”级别创建的单独“libs”文件夹)版本 10 的项目。但是当我们进行构建时,输出包括最近安装在构建服务器上的版本 12。

在这里使用 cmets,我们确保将“复制本地”设置为 True,并且在项目文件中设置了标志。但是,它仍在部署版本 12。因此,我们发现的诀窍是确保在两个引用上也设置了“特定版本”属性。瞧,现在正在部署每个文件的第 10 版!

大家都很高兴。

JH

【讨论】:

【参考方案10】:

如果您的项目不直接加载库,则不会始终部署它,即使它被显式引用!我很困惑,因为我可以在本地 Bin 目录中看到它,但在部署时看不到。 Bin 目录中的 dll 是一个旧文件,在 Clean 过程中没有被删除,这就是我感到困惑的原因。

完全清理和重建,它也不在我的本地 Bin 文件夹中,这向我显示了问题(我只在 web.config 中使用它)。然后我在项目中引用了 dll 文件本身并将其设置为复制到输出以确保它被部署。

【讨论】:

【参考方案11】:

我不确定它是如何在 Visual Studio 2008 中设置的,但我几乎可以肯定您可能一直在使用 Post-Build 事件命令行。在那里,您可以告诉复制部署所需的 DLL 文件。下面给出一个例子:

mkdir $(SolutionDir)\Deployment
copy "$(SolutionDir)Your_Library_Name\Your_Dll_ForDeployement.dll" 
$(SolutionDir)\Deployment\

【讨论】:

我检查了这个,但事实并非如此,谢谢你。【参考方案12】:

我们可以使用&lt;Private&gt;False&lt;/Private&gt; 来不将引用的DLL 文件复制到bin 目录。当我们在单独的 TFS 构建服务器中构建应用程序时,这很有用,我们需要在其中构建应用程序,而不是将 DLL 文件复制到 bin 目录。

【讨论】:

【参考方案13】:

检查引用了 DLL 文件的项目的框架。框架应该是 .NET 4.0。如果框架是客户端配置文件,请更正它。

【讨论】:

【参考方案14】:

添加参数

/deployonbuild=false

到 msbuild 命令行修复了这个问题。

【讨论】:

【参考方案15】:

将旧网站升级到 WebApplications 时遇到类似问题。 “清理解决方案”命令会清除我故意留在 bin 文件夹中的所有外部 DLL 文件。

此外,不可能通过简单地引用它们来自动恢复这些 DLL,因为它们中的许多具有相同的文件名(当您使用许多特定于语言的资源时会发生这种情况)

stevie_c 一样,我利用了 Pre-Build 命令,但让它变得更简单:

我刚刚在 WebApplication 项目属性的 Pre-Build 操作中使用了 xcopy 命令。这样我就可以在构建开始之前带来必要的外部 DLL 文件。

【讨论】:

以上是关于引用 DLL 文件未与部署项目一起复制到 bin,导致错误的主要内容,如果未能解决你的问题,请参考以下文章

部署 ClickOnce 时缺少 dll

Visual Studio/MSBuild 将引用的类库的 app.config 作为 *.dll.config 复制到当前项目的 bin 文件夹

Visual Studio 发布未将所有 DLL 复制到发布文件夹

.net中如何引用Dll文件?

在发布时强制将外部文件复制到 bin 文件夹

将 DLL 添加到 SharePoint bin 文件夹