我们的 Web 应用程序项目中引用了几个外部 DLL 文件。我们有一个用于在托管服务器上安装的部署项目。当我们使用 .NET 3.5 和 Visual Studio 2008 时,DLL 文件被复制到 bin 文件夹中。由于我们已升级到 .NET 4 和 Visual Studio 2010,这种情况不再发生,并且由于找不到引用,我们收到了服务器错误。
CopyLocal 设置为 true,我在 web.config 中找不到任何内容,这表明这是在其他地方设置的。
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 尊重的 Private 节点。
似乎 Visual Studio 2010 中未包含的专用节点 (Copy Local
) 的默认值为 True
,而 MSBuild 将该缺失节点读取为 False
。
我遇到了同样的问题,我没有添加“BeforeBuild”步骤,而是创建了一个简单的测试
[TestMethod]
public void ReferenceAssemblyThatDoesNotCopyToBuildFolder()
{
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler referenceThisButDoNotUseIt = null;
}
并修复了错误无法解决类型“Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler ...”
我的部署项目发生了一些奇怪的事情。当我看到它没有检测到依赖项时,我删除了主要输出并重新添加了它。
依赖项现在显示并在安装时放置在 bin 文件夹中。
我只是遇到了同样的问题,并想分享我的发现,因为它可能对某人有所帮助:
就我而言,原因是在安装某些第三方应用程序期间,程序集安装在 GAC 中。
如果 DLL 文件在 GAC 中,编译器不会费心将其复制到目标文件夹,除非您使用 Junto 提到的项目文件中的“私有”节点将其专门标记为“复制本地”。
问题是,如果您不添加该节点,并且您在一台机器上开发并在另一台机器上构建,并且 DLL 文件仅在构建机器的 GAC 中,则没有私有节点的默认行为将导致文件要在开发机器上正确复制,而不是在构建机器上。
更大的问题是,如果没有直接引用 DLL 文件,但项目引用了第二个项目,该项目又引用了 DLL 文件。在这种情况下,您不能在项目中将 DLL 文件标记为“本地复制”,因为它没有被它引用。因此,如果 DLL 文件存在于 GAC 中 - 它不会被复制到您的输出文件夹中。
这种情况的可能解决方案是:
从 GAC 卸载 DLL 文件
在最终项目中添加对 DLL 文件的直接引用
使用新的强名称重新签署 DLL 文件,这将与 GAC 中的 DLL 文件区分开来。
我遇到了完全相同的问题。我们有一个引用 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”步骤复制了文件。
现在似乎可以构建。
我没有遇到同样的问题,但类似。我有 WPF 主项目和引用的项目,其中引用的项目没有复制。我发现在我的例子中,主项目是为 NET 4.0 客户端配置文件设置的,并且为 NET 3.5 引用。当我将主项目设置为 3.5 时,引用项目的已编译 dll 开始复制。 (我不知道为什么,因为我通过实践解决了它)
我也遇到了类似的问题,引用的 dll 没有复制到已发布文件夹的 bin 中。我使用的是 TFS 签出副本,该副本未将 bin 文件夹包含到应用程序中。 -> 所以只包含 bin 文件夹。 -> 构建引用的应用程序 -> 发布网站项目现在我在发布的文件夹中看到 bin 中所有引用的 dll
我对 VS 2012 Express 也有类似的问题。我在我的项目中使用了 Tesseract 库。一切都很顺利,直到我在一个不止一个项目的解决方案中使用了这个项目。问题是一些通常放在文件夹 bin/debug/x86 或 bin/debug/x64 中的 DLL(liblept168.dll、libtesseract302.dll)仅在我重建整个解决方案时才被复制。更改一行并再次构建它会导致 DLL 被删除而不是复制回来。
我通过向启动项目添加创建缺失 DLL 的项目引用解决了这个问题。
rzen 和其他人,谢谢 - 您的评论为我们带来了解决方案。
我们有一个针对 Microsoft.ReportViewer.Common.dll 和 Microsoft.ReportViewer.WebForms.dll 程序集(我们在“src”级别创建的单独“libs”文件夹)版本 10 的项目。但是当我们进行构建时,输出包括最近安装在构建服务器上的版本 12。
在这里使用注释,我们确保“复制本地”设置为 True,并且在项目文件中设置了标志。但是,它仍在部署版本 12。因此,我们发现的诀窍是确保在两个引用上也设置了“特定版本”属性。瞧,现在正在部署每个文件的第 10 版!
人们欢欣鼓舞。
JH
如果您的项目不直接加载库,则不会始终部署它,即使它被显式引用!我很困惑,因为我可以在本地 Bin 目录中看到它,但在部署时却看不到。 Bin 目录中的 dll 是一个旧文件,在清理过程中没有被删除,这就是我感到困惑的原因。
完全清理和重建,它也不在我的本地 Bin 文件夹中,这向我显示了问题(我只在 web.config 中使用它)。然后我在项目中引用了 dll 文件本身并将其设置为复制到输出以确保它被部署。
我不确定它是如何在 Visual Studio 2008 中设置的,但我几乎可以肯定您可能一直在使用 Post-Build 事件命令行。在那里,您可以告诉复制部署所需的 DLL 文件。下面给出一个例子:
mkdir $(SolutionDir)\Deployment
copy "$(SolutionDir)Your_Library_Name\Your_Dll_ForDeployement.dll"
$(SolutionDir)\Deployment\
我们可以使用 <Private>False</Private>
来不将引用的 DLL 文件复制到 bin
目录。当我们在单独的 TFS 构建服务器中构建应用程序时,这很有用,我们需要在其中构建应用程序,而不是将 DLL 文件复制到 bin
目录。
检查引用了 DLL 文件的项目的框架。框架应该是 .NET 4.0。如果框架是客户端配置文件,请更正它。
添加参数
/deployonbuild=假
到 msbuild 命令行解决了这个问题。
在将旧网站升级到 WebApplications 时遇到了类似的问题。 “清理解决方案”命令将清除我故意留在 bin 文件夹中的所有外部 DLL 文件。
此外,不可能通过简单地引用它们来自动恢复这些 DLL,因为它们中的许多具有相同的文件名(当您使用许多特定于语言的资源时会发生这种情况)
像 stevie_c 一样,我利用了 Pre-Build 命令,但让它变得更简单:
我只是在 WebApplication 项目属性的 Pre-Build 操作中使用了 xcopy 命令。这样我就可以在构建开始之前带来必要的外部 DLL 文件。