7

この質問は何度も尋ねられている可能性があり、ここでの検索機能とGoogleの使用が苦手なだけかもしれませんが、この質問に対する答えはまだ見つかりません.

現在、プロジェクト X、プロジェクト Y、プロジェクト Z (マッピングのみを保持) の 2 つのプロジェクトがあります。

プロジェクト X は、私のセッション ファクトリなどを保持する FluentNhibernate プロジェクトです。したがって、これはマッピングがロードされる場所でもあります(これは重要であり、私が抱えている問題の全体的な理由であると思われます)

Project X では、Microsoft.SqlServer.Types.dll を使用するアセンブリを参照しました。

プロジェクト Y は、データベース接続にプロジェクト X を使用するサービスです。

すべてのプロジェクト ビルドは私の開発マシンで完全に検出および実行されますが、サーバーにデプロイすると機能しませんでした (実行時エラー)。エラーは、FluentNHibernate アセンブリが欠落していることを示していたため、かなりあいまいでしたが、そうではありませんでした。

Procmon.exe は幸運にも、サーバーに SQL Server がインストールされていないため、Microsoft.SqlServer.Types.dll をロードしようとしているコードを示しました (私のクライアントもインストールされていませんが、この .DLL をインストールする可能性が最も高い管理スタジオがあります)。 .

これまでのところ、DLL をコピーしたところうまくいきました (やった!)。

ここで、アセンブリをプロジェクト X に追加して、この参照がプロジェクト X を使用して他のプロジェクトにコピーされるようにすることを考えました。

悲しいことに、これでも .dll が参照プロジェクト Y にコピーされません。

これを実現する方法はありますか、それともこの Visual Studio は巧妙で、プロジェクト Y がこの .dll を必要としないことを認識しているため、コピーを拒否していますか?

(プロジェクト Z は実際の参照を必要とし、プロジェクト X は実行時にこのアセンブリをロードするため、Z と X の間に「ハード」参照はありません)

正直なところ、なぜこのように動作するのか(そして理想的には、私が望むように動作させる方法)を知りたいので、Stackoverflowの天才はこれに光を当てることができますか?

4

3 に答える 3

7

この質問はすでに回答されていますが、すべての間接参照をプロジェクトの出力ディレクトリにコピーするための一般的なフェールセーフ メソッドを含めることにしました。

  1. 出力に含めたいすべての参照に対して、Copy Localtrueに設定します。
  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 に追加すると考えました。

あなたはまだ Microsoft.SqlServer.Types.dll について話しているのですか?

私はしばらく前に同じ問題を抱えていましたが、実際には sqlserver 型をインストールでコピーして再配布するべきではありません。それを「インストール」する正しい方法は、SQL Server ランタイムをダウンロードすることです (これは SQL Server 管理ツールに含まれているため、ローカルで機能します)。

少し前のことなので、次の情報が正しく機能するかどうかは 100% わかりませんが、 Microsoft® SQL Server® 2012のみに Microsoft® System CLR タイプをインストールしてみてください。このダウンロード ページで、[Install Instructions] を展開し、[CLR Types download] まで下にスクロールします...

SQL Server 2008 については、このリンクを使用してください

これを対象サーバーにインストールします。これは、このタイプのdllを実行するために必要なものだけをインストールします...

于 2013-10-02T09:54:07.110 に答える
-1

Microsoft の回答が役に立つかもしれません: https://connect.microsoft.com/VisualStudio/feedback/details/652785/visual-studio-does-not-copy-referenced-assemblies-through-the-reference-hierarchy

于 2015-03-12T12:02:48.867 に答える