78

1つの.NETDLLアセンブリとVB.NETコンソールアプリケーションプロジェクトによって参照される1つのC#クラスライブラリプロジェクトを1つのコマンドラインコンソール実行可能ファイルにマージしたいと思います。

コマンドラインからILMergeを使用してこれを行うことができますが、この参照アセンブリとプロジェクトのマージをVisualStudioプロジェクトに統合したいと思います。私の読書から、MSBuildタスクまたはターゲットを介してこれを実行し、C#/ VB.NETプロジェクトファイルに追加するだけでよいことを理解していますが、MSBuildは大きなトピックであるため、具体的な例は見つかりません。さらに、ビルド後のイベントにILMergeコマンドを追加する参照がいくつか見つかりました。

  1. ILMergeをVisualStudio(C#/ VB.NET)プロジェクト(MSBuildプロジェクト)に統合して、参照されているすべてのアセンブリ(copy-local = true)を1つのアセンブリにマージするにはどうすればよいですか?

  2. これは、可能なILMerge.Targetsファイルにどのように結びついていますか?

  3. ビルド後のイベントを使用する方が良いですか?

4

9 に答える 9

69

MSBuildILMergeタスク」(またはMSBuild.ILMerge.Task)NuGetパッケージを使用すると、このプロセスが非常に簡単になります。デフォルトでは、「ローカルコピー」参照をメインアセンブリにマージします。

注:ILMerge.MSBuild.Tasksパッケージの名前は似ていますが、これは、DavideIcardiが彼の回答で述べたものとは異なります。ここで提案しているのは、2014年8月に最初に公開されたものです。

于 2014-10-13T19:26:32.170 に答える
21

ここに代替ソリューションがあります:

1)nugetからILMerge.MSBuild.Tasksパッケージをインストールします

PM>インストール-パッケージILMerge.MSBuild.Tasks

2)以下のコードを追加して、マージするプロジェクトの*.csprojファイルを編集します。

  <!-- Code to merge the assemblies into one:setup.exe -->
  <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyFile="$(SolutionDir)\packages\ILMerge.MSBuild.Tasks.1.0.0.3\tools\ILMerge.MSBuild.Tasks.dll" />
  <Target Name="AfterBuild">
    <ItemGroup>
      <MergeAsm Include="$(OutputPath)$(TargetFileName)" />
      <MergeAsm Include="$(OutputPath)LIB1_To_MERGE.dll" />
      <MergeAsm Include="$(OutputPath)LIB2_To_MERGE.dll" />
    </ItemGroup>
    <PropertyGroup>
      <MergedAssembly>$(ProjectDir)$(OutDir)MERGED_ASSEMBLY_NAME.exe</MergedAssembly>
    </PropertyGroup>
    <Message Text="ILMerge @(MergeAsm) -&gt; $(MergedAssembly)" Importance="high" />
    <ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" />
  </Target>

3)通常どおりプロジェクトをビルドします。

于 2012-11-19T00:08:44.453 に答える
18

スコット・ハンゼルマンのソリューションを実装する一部の人々に役立つ可能性のあるいくつかの詳細情報。

これを最初に設定したとき、System.Coreなどへの参照を解決できないという不満がありました。これは.NET4のサポートと関係があります。.NET 4Frameworkディレクトリを指す/lib引数を含めると、修正されます(実際には、$(MSBuildBinPath)を含めるだけです)。

/lib:$(MSBuildBinPath)

次に、マージ中にIlMergeがハングすることがわかりました。少しのCPUとたくさんのRAMを使用していましたが、何も出力していませんでした。もちろん、stackoverflowの修正を見つけました。

/targetplatform:v4

また、Scottのブログ記事で使用されているMSBuildプロパティの一部は、プロジェクトのディレクトリからのMsBuildの実行に依存していることがわかったので、それらを少し調整しました。

次に、targets&ilmerge.exeをソースツリーのtoolsフォルダーに移動しました。これには、パスをさらに微調整する必要がありました...

私は最終的に、Scottの元の記事の要素を置き換えるために次のExec要素を使用することになりました。

<Exec Command="&quot;$(MSBuildThisFileDirectory)Ilmerge.exe&quot; /lib:$(MSBuildBinPath) /targetplatform:v4 /out:@(MainAssembly) &quot;$(MSBuildProjectDirectory)\@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" /> 

更新 また、Logic Labsは、CopyLocalの動作を維持し、Nugetパッケージを使用している場合はCopyLocalからilMergedアセンブリを除外することが不可欠であると回答しました。それ以外の場合は、マージされていない参照アセンブリのパッケージディレクトリごとに/lib引数を指定する必要があります。

于 2012-05-10T14:58:01.123 に答える
16

http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspxの記事「VisualStudioでの単一アセンブリでの言語のILMergeおよびMSBuildとのシームレスな混合」では、 VisualStudioプロジェクト内でILMergeおよびMSBuildを使用する方法を示しています。

于 2010-03-31T20:43:19.203 に答える
9

http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspxの記事で見つけた問題の1つ。

ILMergeを望まない参照がある場合、記事のコードは、デフォルトのCopyLocalの動作をオーバーライドして何もしないため、失敗します。

これを修正するには-代わりに:

<Target Name="_CopyFilesMarkedCopyLocal"/> 

代わりに、このエントリをターゲットファイルに追加します(.NET 3.5のみ)(非ilmergeコピーローカルファイルを除外し、それらを通常どおりに処理するため)

<Target Name="AfterResolveReferences">
    <Message Text="Filtering out ilmerge assemblies from ReferenceCopyLocalPaths" Importance="High" />
    <ItemGroup>
        <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.IlMerge)'=='true'" />
    </ItemGroup>
</Target>
于 2012-03-07T20:02:04.803 に答える
4

これは、参照されるアセンブリを出力アセンブリにマージする方法を示す優れた記事です。これは、msbuildを使用してアセンブリをマージする方法を正確に示しています。

于 2010-03-31T20:50:57.140 に答える
1

私の2セント-@Jasonの応答を取得し、すべての*.dllが同じフォルダー内にあるbin/Debugフォルダーに*.exeを生成したいソリューションで機能するようにしました。

<Exec Command="&quot;$(SolutionDir)packages\ILMerge.2.13.0307\Ilmerge.exe&quot; /wildcards /out:&quot;$(SolutionDir)..\$(TargetFileName)&quot; &quot;$(TargetPath)&quot; $(OutDir)*.dll" /> 

注:このソリューションは、明らかにILMergenugetパッケージバージョンにハードコードされています。改善すべき提案があれば教えてください。

于 2014-11-13T18:46:36.377 に答える
1

以下のコードを追加して、マージするプロジェクトの*.csprojファイルを編集します。

<Target Name="AfterBuild" Condition=" '$(ConfigurationName)' == 'Release' " BeforeTargets="PostBuildEvent">
  <CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
    <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
  </CreateItem>
  <Exec Command="&quot;$(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exe&quot; /internalize:&quot;$(MSBuildProjectPath)ilmerge.exclude&quot; /ndebug  /out:@(MainAssembly)  &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
  <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

ノート:

  1. $(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exeにあるパスに置き換えますILMerge.exe
  2. ターゲット内のを削除してCondition、デバッグ時にマージすることもできますが、デバッガーが機能しない可能性があります
  3. 何も除外していない場合は、以下を削除できます。/internalize:&quot;$(MSBuildProjectPath)ilmerge.exclude&quot;
于 2020-05-20T21:09:05.767 に答える
0

Jomoによるこの記事をチェックしてください。彼はILMergeをmsbuildシステムにハックするための迅速なプロセスを持っています

于 2010-03-31T20:46:31.420 に答える