visual-studio 如何将 ILMerge 集成到 Visual Studio 构建过程中以合并程序集?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2556048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Integrate ILMerge into Visual Studio Build Process to Merge Assemblies?
提问by AMissico
I want to merge one .NET DLL assembly and one C# Class Library project referenced by a VB.NET Console Application project into one command-line console executable.
我想将一个 .NET DLL 程序集和一个由 VB.NET 控制台应用程序项目引用的 C# 类库项目合并到一个命令行控制台可执行文件中。
I can do this with ILMerge from the command-line, but I want to integrate this merging of reference assemblies and projects into the Visual Studio project. From my reading, I understand that I can do this through a MSBuild Task or a Target and just add it to a C#/VB.NET Project file, but I can find no specific example since MSBuild is large topic. Moreover, I find some references that add the ILMerge command to the Post-build event.
我可以从命令行使用 ILMerge 执行此操作,但我想将此引用程序集和项目的合并集成到 Visual Studio 项目中。从我的阅读中,我知道我可以通过 MSBuild 任务或目标来做到这一点,并将其添加到 C#/VB.NET 项目文件中,但我找不到具体的例子,因为 MSBuild 是一个很大的话题。此外,我找到了一些将 ILMerge 命令添加到 Post-build 事件的参考。
How do I integrate ILMerge into a Visual Studio (C#/VB.NET) project, which are just MSBuild projects, to merge all referenced assemblies (copy-local=true) into one assembly?
How does this tie into a possible ILMerge.Targets file?
Is it better to use the Post-build event?
如何将 ILMerge 集成到 Visual Studio (C#/VB.NET) 项目中,这些项目只是 MSBuild 项目,以将所有引用的程序集 (copy-local=true) 合并到一个程序集中?
这如何与可能的 ILMerge.Targets 文件相关联?
使用 Post-build 事件更好吗?
采纳答案by AMissico
The article Mixing Languages in a Single Assembly in Visual Studio seamlessly with ILMerge and MSBuildat http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspxdemonstrates how to use ILMerge and MSBuild within a Visual Studio Project.
文章混合在单个汇编语言在Visual Studio无缝ILMerge和的MSBuild在http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx演示了如何将Visual Studio项目中使用ILMerge和的MSBuild。
回答by Holistic Developer
The "MSBuild ILMerge task" (or MSBuild.ILMerge.Task) NuGet package makes this process quite simple. It defaults to merging any "copy local" references into your main assembly.
“ MSBuild ILMerge 任务”(或MSBuild.ILMerge.Task)NuGet 包使这个过程非常简单。它默认将任何“复制本地”引用合并到您的主程序集中。
Note:Although the packages have similar names, this one is different from ILMerge.MSBuild.Tasksthat Davide Icardi mentioned in his answer. The one I'm suggesting here was first published in August 2014.
注意:虽然这些包的名称相似,但这与ILMerge.MSBuild.TasksDavide Icardi 在他的回答中提到的不同。我在这里建议的那个是在 2014 年 8 月首次发布的。
回答by Jason Duffett
Some more information that might be useful to some people implementing Scott Hanselman's solution.
一些可能对实施Scott Hanselman 解决方案的人有用的更多信息。
When I first set this up it would complain about not being able to resolve references to System.Core, etc. It is something to do with .NET 4 support. Including a /lib argument pointing to the .NET 4 Framework directory fixes it (in fact just include the $(MSBuildBinPath)).
当我第一次设置它时,它会抱怨无法解析对 System.Core 等的引用。这与 .NET 4 支持有关。包含一个指向 .NET 4 Framework 目录的 /lib 参数可以修复它(实际上只包含 $(MSBuildBinPath))。
/lib:$(MSBuildBinPath)
/lib:$(MSBuildBinPath)
I then found that IlMerge would hang while merging. It was using a bit of CPU and a lot of RAM but wasn't outputting anything. I found the fix on stackoverflow of course.
然后我发现 IlMerge 在合并时会挂起。它使用了一点 CPU 和大量 RAM,但没有输出任何内容。我当然找到了对 stackoverflow的修复。
/targetplatform:v4
/targetplatform:v4
I also found that some of the MSBuild properties used in Scott's blog article relied on executing MsBuild from the project's directory, so I tweaked them a bit.
我还发现 Scott 的博客文章中使用的一些 MSBuild 属性依赖于从项目目录中执行 MsBuild,因此我对它们进行了一些调整。
I then moved the targets & ilmerge.exe to the tools folder of our source tree which required another small tweak to the paths...
然后我将目标和 ilmerge.exe 移动到我们源树的工具文件夹中,这需要对路径进行另一次小调整...
I finally ended up with the following Execelement to replace the one in Scott's original article:
我最终使用以下Exec元素来替换 Scott 原始文章中的元素:
<Exec Command=""$(MSBuildThisFileDirectory)Ilmerge.exe" /lib:$(MSBuildBinPath) /targetplatform:v4 /out:@(MainAssembly) "$(MSBuildProjectDirectory)\@(IntermediateAssembly)" @(IlmergeAssemblies->'"%(FullPath)"', ' ')" />
UPDATEI also found Logic Labs answerabout keeping the CopyLocal behaviour and just excluding ilMerged assemblies from CopyLocal essential if you are using Nuget packages. Otherwise you need to specify a /lib argument for each package directory of referenced assemblies that aren't being merged.
更新我还发现Logic Labs 的答案是关于保持 CopyLocal 行为,如果您使用 Nuget 包,则仅从 CopyLocal 中排除 ilMerged 程序集必不可少。否则,您需要为未合并的引用程序集的每个包目录指定一个 /lib 参数。
回答by Davide Icardi
Here an alternative solution:
这里有一个替代解决方案:
1) Install ILMerge.MSBuild.Tasks package from nuget
1)从nuget安装ILMerge.MSBuild.Tasks包
PM> Install-Package ILMerge.MSBuild.Tasks
PM> 安装包 ILMerge.MSBuild.Tasks
2) Edit the *.csproj file of the project that you want to merge by adding the code below:
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) -> $(MergedAssembly)" Importance="high" />
<ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" />
</Target>
3) Build your project as usual.
3) 像往常一样构建你的项目。
回答by Logic Labs
One issue I found with the article at: http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx.
我在这篇文章中发现了一个问题:http: //www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlessWithILMergeAndMSBuild.aspx。
If you have any references that you do not wish to ILMerge then the code in the article fails because it overrides the default CopyLocal behaviour to do nothing.
如果您有任何不希望 ILMerge 的引用,那么本文中的代码将失败,因为它覆盖了默认的 CopyLocal 行为而什么也不做。
To fix this - Instead of:
要解决此问题 - 而不是:
<Target Name="_CopyFilesMarkedCopyLocal"/>
Add this entry to the targets file instead (.NET 3.5 only) (to filter out the non-ilmerge copylocal files, and treat them as normal)
将此条目添加到目标文件中(仅限 .NET 3.5)(过滤掉非 ilmerge copylocal 文件,并将它们视为正常)
<Target Name="AfterResolveReferences">
<Message Text="Filtering out ilmerge assemblies from ReferenceCopyLocalPaths" Importance="High" />
<ItemGroup>
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.IlMerge)'=='true'" />
</ItemGroup>
</Target>
回答by Rohan West
回答by rui
My 2 cents - I picked up @Jason's response and made it work for my solution where I wanted to generate the *.exe in the bin/Debug folder with all *.dlls inside the same folder.
我的 2 美分 - 我收到了@Jason 的回复,并使其适用于我的解决方案,我想在 bin/Debug 文件夹中生成 *.exe,所有 *.dll 都在同一文件夹中。
<Exec Command=""$(SolutionDir)packages\ILMerge.2.13.0307\Ilmerge.exe" /wildcards /out:"$(SolutionDir)..$(TargetFileName)" "$(TargetPath)" $(OutDir)*.dll" />
Note: This solution is obviously hardcoded into the ILMerge nuget package version. Please let me know if you have some suggestions to improve.
注意:此解决方案显然已硬编码到 ILMerge nuget 包版本中。如果您有一些改进建议,请告诉我。
回答by N T
Edit the *.csproj file of the project that you want to merge by adding the code below:
通过添加以下代码来编辑要合并的项目的 *.csproj 文件:
<Target Name="AfterBuild" Condition=" '$(ConfigurationName)' == 'Release' " BeforeTargets="PostBuildEvent">
<CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
<Output ItemName="AssembliesToMerge" TaskParameter="Include" />
</CreateItem>
<Exec Command=""$(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exe" /internalize:"$(MSBuildProjectPath)ilmerge.exclude" /ndebug /out:@(MainAssembly) "@(IntermediateAssembly)" @(AssembliesToMerge->'"%(FullPath)"', ' ')" />
<Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>
Notes:
笔记:
- Replace
$(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exewith whatever path you have theILMerge.exein. - You can remove the
Conditionin the target to also merge on Debug but then the Debugger might not work - If you are not excluding anything you can remove:
/internalize:"$(MSBuildProjectPath)ilmerge.exclude"
- 替换
$(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exe为您所在的任何路径ILMerge.exe。 - 您可以删除
Condition目标中的 也可以在 Debug 上合并,但随后调试器可能无法工作 - 如果您不排除任何内容,您可以删除:
/internalize:"$(MSBuildProjectPath)ilmerge.exclude"
回答by JaredPar
Check out this article by Jomo. He has a quick process to hack ILMerge into the msbuild system
查看 Jomo 的这篇文章。他有一个快速的过程来破解 ILMerge 到 msbuild 系统

