2016-09-02 6 views
12

私は、いくつかのCLRクラス(Managed.dllと呼ぶ)をエクスポートするマネージドDLLアセンブリを生成する、混合モードのC++プロジェクトを持っています。このプロジェクトはネイティブDLLを使用しています(Native.dllと呼んでいます)。Visual Studioプロジェクトでネイティブの依存関係をローカルにコピー

Client.exeを生成する別のプロジェクトからManaged.dllを参照すると、Client.exeと同じフォルダにNative.dllを手動でコピーする必要がある以外は、すべて正常に動作します。

ローカルに(Client.exeのbinフォルダ内に)VSを納得させる方法があれば、Managed.dllだけでなくNative.dllも同様ですか?

マニフェストに依存関係アセンブリとしてNative.dllを含めることを試みたが、これは役に立たなかった。

編集

Managed.dllは再配布可能なアセンブリになるだろう。それは "C:\ Program Files ....."内のフォルダにインストールされます。 Visual Studioを使用している開発者がManaged.dllへの参照を追加すると、Native.dllもプロジェクトの\ binフォルダにコピーされます。

+0

[Visual StudioでDLLの依存関係をコピーする](http://stackoverflow.com/questions/1043913/copying-a-dlls-dependencies-in-visual-studio)というタイトルの記事は役に立ちますか? –

+0

私はこれが私が必要としているのではないかと心配しています。 Managed.dllとNative.dllを配布したいです。ライブラリのユーザーがManaged.dllを参照すると、プロジェクトのbinフォルダにローカルにコピーされたNative.dllが必要になります。 – Trifon

答えて

8

先のフォルダにDLLをコピーするVSを伝えるには、いくつかの方法があります。

1.Add DLLプロジェクトのリソースとしては。 dllが新しい場合はVSにコピーします。

2. dllプロジェクトを参照する新しいプロジェクトを追加し、OutDirを目的のフォルダに設定します。このプロジェクトはdllをコピーするだけです。 PreBuildEvent 4.Use

vcxprojファイル内PostBuildEvent 3.Use

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 
    <ClCompile> 
    </ClCompile> 
    <Link> 
    </Link> 
    <PostBuildEvent> 
    <Command> 
     echo off 
     mkdir "$(ProjectDir)..\..\bin\$(Configuration)\" 
     copy "$(OutDir)xxx.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" 
     echo on 
    </Command> 
    </PostBuildEvent> 
</ItemDefinitionGroup> 

vcxprojファイル内

5.Use CustomBuild vcxprojファイル内

<ItemGroup> 
<CustomBuild Include="..\..\xxx.dll"> 
    <FileType>Document</FileType> 
    <Command> 
    call mkdir &quot;$(OutDir)&quot; 2&gt;nul &amp; 
    copy /Y &quot;..\..\xxx.dll&quot; &quot;$(OutDir)xxx.dll&quot; 
    </Command> 
    <Message>Copying xxx.dll to $(OutDir)\xxx.dll</Message> 
    <Outputs>$(OutDir)\xxx.dll</Outputs> 
</CustomBuild> 
</ItemGroup> 

メイク6.Use makefileにdllをコピーします。そしてコピージョブを行う

7.Write batファイルを構築し、またからDLLをダウンロードすることができますPythonなど3-6

8.Useスクリプト、のようにbatファイルを呼び出すためにNMAKEを使用インターネット。そして、3-6のようにpyファイルを呼び出します。

は、Gradleのように、ツールはあまりにも助けることができる構築9.Other

10.MakeそれNuGetプラグイン

11.Sometimes私はバットを書き、手動でバットを実行します。

アップデート01(自己抽出DLLの例):マネージDLLのリソース

2.Addこのinit()メソッドとして

1.AddあなたネイティブDLL

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Security.Cryptography; 
using System.Text; 
using System.Threading.Tasks; 

namespace DllSelfExtract 
{ 
    public class SelfExtract 
    { 
     public static void Init() 
     { 
      String managedDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; 
      String nativeDllPath = managedDllPath.Replace("file:///", "").Replace("DllSelfExtract.DLL", "TestDll.dll"); 
      if(!File.Exists(nativeDllPath)) 
      { 
       Stream dllIn = Assembly.GetExecutingAssembly().GetManifestResourceStream("DllSelfExtract.TestDll.dll"); 
       if (dllIn == null) return; 

       using (Stream outFile = File.Create(nativeDllPath)) 
       { 
        const int sz = 4096; 
        byte[] buf = new byte[sz]; 
        while (true) 
        { 
         int nRead = dllIn.Read(buf, 0, sz); 
         if (nRead < 1) 
          break; 
         outFile.Write(buf, 0, nRead); 
        } 
       } 
      } 

      //LoadLibrary Here 
     } 
    } 
} 

3 。

1.Create新しいNuGetプロジェクト

2.Placeの管理:あなたのマネージDLLを使用するプロジェクトでは、最初のinit()メソッド

SelfExtract.Init(); 

アップデート02(NuGet例)を呼び出します/ libディレクトリのアセンブリ

3.非管理共有ライブラリおよび関連ファイルを/ buildサブディレクトリに配置し、管理されていないすべての* .dllの名前を* .dl_

に変更します10

4.Add以下の内容のようなもので/ buildサブディレクトリ内のカスタム.targetsファイル:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
    <AvailableItemName Include="NativeBinary" /> 
    </ItemGroup> 
    <ItemGroup> 
    <NativeBinary Include="$(MSBuildThisFileDirectory)*"> 
     <TargetPath></TargetPath> 
    </NativeBinary> 
    </ItemGroup> 
    <PropertyGroup> 
    <PrepareForRunDependsOn> 
     $(PrepareForRunDependsOn); 
     CopyNativeBinaries 
    </PrepareForRunDependsOn> 
    </PropertyGroup> 
    <Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory"> 
    <Copy SourceFiles="@(NativeBinary)" 
      DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')" 
      Condition="'%(Extension)'=='.dl_'"> 
     <Output TaskParameter="DestinationFiles" ItemName="FileWrites" /> 
    </Copy> 
    <Copy SourceFiles="@(NativeBinary)" 
      DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')" 
      Condition="'%(Extension)'!='.dl_'"> 
     <Output TaskParameter="DestinationFiles" ItemName="FileWrites" /> 
    </Copy> 
    </Target> 
</Project> 

5.Addが

<files> 
    <file src="lib\" target="lib" /> 
    <file src="tools\" target="tools" /> 
    <file src="content\" target="content" /> 
    <file src="build\" target="build" /> 
</files> 

6 Package.nuspecにビルドフォルダのルールを構築。パッケージを作る

7.あなたの他のC#プロジェクトでは、このNuGetパッケージを追加するだけです。

+0

ありがとうございます。これらのメソッドはすべて有効で便利なので、MYプロジェクトで使用できます。問題は、Visual Studioプロジェクトではなく、複数ファイルアセンブリ(Managed.dllとNative.dllで構成)を配布したいということです。 – Trifon

+0

@Trifon Managed.dllのリソースとしてNative.dllを追加するのはどうでしょうか? Managed.dllで、Native.dllをロードする前に、Managed.dllからNativeを抽出しないとNative.dllが適切な場所にあるかどうかを検出しますか?しかし、私はインターネットからのダウンロードが良いと思う。 – neohope

+0

はいこれは、私のことを念頭に置いておくべき解決策です。このようなものは成功しません。[リンク](http://stackoverflow.com/a/768429/3260013) – Trifon

5

リンカープロパティで/ASSEMBLYLINKRESOURCEオプションを使用するのが最も簡単な解決策です。 Visual Studioでは、ネイティブdllをアセンブリの一部として扱います。

  • 右プロジェクト名をクリックして選択します。また、マイクロソフトが提供しているマニュアルによると、ネイティブのDLLは、Visual C++プロジェクトでこのリンカオプションを設定するには、キャッシュ

    グローバルアセンブリ内に設置することができますプロパティ

  • 総会リンクRESOURCを見つける入力プロパティページではリンカフォルダ
  • を選択しますeオプション
  • ネイティブアセンブリのファイル名を書き込みます。 MyNative.dll

ネイティブdllを出力フォルダにコピーするには、Post Buildイベントが必要です。

他のVisual Projectから管理対象アセンブリを参照すると、管理対象アセンブリと共にネイティブdllを/ binフォルダに強制的にコピーします。

+0

これをお読みください、あなたはナゲットパッケージを試すことができます。 http://stackoverflow.com/questions/19478775/add-native-files-from-nuget-package-to-project-output-directory – neohope

関連する問題