7

这个问题可能已经被问过多次,也许我只是不擅长使用这里的搜索功能以及谷歌,但我还没有找到这个问题的答案。

我目前有两个项目,项目 X、项目 Y 和项目 Z(仅包含映射)

Project X 是一个 FluentNhibernate 项目,其中包含我的 sessionfactories 和类似的东西。所以这也是加载映射和事情的地方(这很重要,我怀疑这可能是我遇到问题的全部原因)

现在在 Project X 中,我引用了一个使用 Microsoft.SqlServer.Types.dll 的程序集。

项目 Y 是一项使用项目 X 进行数据库连接的服务。

所有 probjects 构建都可以在我的开发机器上找到并完美运行,但是当部署到我们的服务器时它们无法运行(运行时错误)。该错误非常模糊,因为它指向缺少的 FluentNHibernate 程序集,但事实并非如此。

Procmon.exe 幸运地显示了尝试加载 Microsoft.SqlServer.Types.dll 的代码,因为服务器没有安装 SQL Server(我的客户端也没有安装,但它有一个管理工作室,很可能也安装了这个 .DLL) .

到目前为止一切顺利,复制了 DLL 并且它工作了(耶!)。

现在我想我会将程序集添加到项目 X 以确保将此引用复制到使用项目 X 的​​其他项目。这没有发生......所以我尝试将“复制本地”设置设置为 true。

遗憾的是,这仍然没有将 .dll 复制到引用项目 Y。

有没有办法实现这一点,或者这个 Visual Studio 是否聪明并意识到项目 Y 不需要这个 .dll 并因此拒绝复制它?

(由于项目 Z 需要实际引用,并且项目 X 在运行时加载此程序集,因此 Z 和 X 之间没有“硬”引用)

任何 Stackoverflow 天才都可以对此有所了解,因为老实说,我想知道它为什么会这样(理想情况下是让它表现得像我想要的那样)。

4

3 回答 3

7

这个问题已经得到解答,但我想我将包含一个通用的故障安全方法,用于将所有间接引用复制到项目的输出目录中。

  1. 对于要包含在输出中的所有引用,将Copy Local设置为true 。
  2. 将复制的间接依赖项代码(见下文)保存到具有名称CopyIndirectDependencies.targets的文件中,并将目标文件放在项目目录中。
  3. 编辑您的.csproj或以包含对您添加的文件.vbproj的导入。.targets请参见下面的示例。
  4. 构建您的项目,您应该将辅助依赖项自动复制到构建输出中。

CopyIndi​​rectDependencies.targets文件内容

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <CopyIndirectDependencies   
      Condition="'$(CopyIndirectDependencies)'==''">true</CopyIndirectDependencies>
    <CopyIndirectDependenciesPdb
      Condition="'$(CopyIndirectDependenciesPdb)'==''">false</CopyIndirectDependenciesPdb>
    <CopyIndirectDependenciesXml
      Condition="'$(CopyIndirectDependenciesXml)'==''">false</CopyIndirectDependenciesXml>
  </PropertyGroup>


  <!-- BuildXxx part -->

  <Target Name="CopyIndirectDependencies"
          Condition="'$(CopyIndirectDependencies)'=='true'"
          DependsOnTargets="DetectIndirectDependencies">
    <Copy Condition="'%(IndirectDependency.FullPath)'!=''"
          SourceFiles="%(IndirectDependency.FullPath)"
          DestinationFolder="$(OutputPath)"
          SkipUnchangedFiles="true" >
      <Output TaskParameter="CopiedFiles"
              ItemName="IndirectDependencyCopied" />
    </Copy>
    <Message Importance="low"
             Condition="'%(IndirectDependencyCopied.FullPath)'!=''
               and '%(IndirectDependencyCopied.Extension)'!='.pdb'
               and '%(IndirectDependencyCopied.Extension)'!='.xml'"
             Text="Indirect dependency copied: %(IndirectDependencyCopied.FullPath)" />
  </Target>

  <Target Name="DetectIndirectDependencies"
          DependsOnTargets="ResolveAssemblyReferences">

    <Message Importance="low"
             Text="Direct dependency: %(ReferencePath.Filename)%(ReferencePath.Extension)" />
    <Message Importance="low"
             Text="Indirect dependency: %(ReferenceDependencyPaths.Filename)%(ReferenceDependencyPaths.Extension)" />

    <!-- Creating indirect dependency list -->
    <CreateItem Include="%(ReferenceDependencyPaths.FullPath)"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>
    <CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).xml"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesXml)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>
    <CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).pdb"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesPdb)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>

    <!-- Filtering indirect dependency list by existence -->
    <CreateItem Include="%(_IndirectDependency.FullPath)"
                Condition="Exists('%(_IndirectDependency.FullPath)')">
      <Output TaskParameter="Include"
              ItemName="IndirectDependency"/>
    </CreateItem>

    <!-- Creating copied indirect dependency list -->
    <CreateItem Include="@(_IndirectDependency->'$(OutputPath)%(Filename)%(Extension)')">
      <Output TaskParameter="Include"
              ItemName="_ExistingIndirectDependency"/>
    </CreateItem>

    <!-- Filtering copied indirect dependency list by existence -->
    <CreateItem Include="%(_ExistingIndirectDependency.FullPath)"
                Condition="Exists('%(_ExistingIndirectDependency.FullPath)')">
      <Output TaskParameter="Include"
              ItemName="ExistingIndirectDependency"/>
    </CreateItem>

  </Target>


  <!-- Build sequence modification -->

  <PropertyGroup>
    <CoreBuildDependsOn>
      $(CoreBuildDependsOn);
      CopyIndirectDependencies
    </CoreBuildDependsOn>
  </PropertyGroup>
</Project>

带导入的示例项目

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  ...

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="CopyIndirectDependencies.targets" /> <!-- ADD THIS LINE!! -->

  ...

</Project>

来源: http ://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html

于 2013-10-02T11:58:34.473 回答
2

现在我想我会将程序集添加到项目 X 以确保将此引用复制到使用项目 X 的​​其他项目。这没有发生......所以我尝试将“复制本地”设置设置为 true。

您还在谈论 Microsoft.SqlServer.Types.dll 对吗?

前段时间我遇到了同样的问题,实际上 sqlserver 类型不应该在您的安装中复制和重新分发。“安装”它的正确方法是下载 sql server 运行时(它包含在 sql server 管理工具中,这就是它在本地为您工作的原因)。

因为是前段时间,所以我不能 100% 确定以下信息是否正确以及是否有效,我只是尝试安装Microsoft® System CLR Types for Microsoft® SQL Server® 2012。在此下载页面上展开安装说明并向下滚动到 CLR 类型下载...

将此链接用于SQL Server 2008

在目标服务器上安装它。这只会安装运行这种类型的 dll 所需的东西......

于 2013-10-02T09:54:07.110 回答