The original: Two ways that the WPF program embeds DLLs into the EXE
Two ways that a WPF program embeds DLLs into an EXE
This article can be seen as the continuation of the Visual Studio version Conversion tool WPF version of Open source, about the Visual Studio version Conversion tool WPF version of Open source can see the underground address (two is the same):
- Open source China http://my.oschina.net/chinesedragon/blog/308336
- Cnblogs http://www.cnblogs.com/luoshupeng/p/3946635.html
* * Blog Park markdown Editor really not, or trouble everyone steady to http://my.oschina.net/chinesedragon/blog/309223 watch it * *
Introduction
The first few wrote a gadget ———— the Visual Studio version Conversion tool, because using WPF as the interface, Therefore, this applet must be run with two DLL:Microsoft.Expression.Interactions.dll and System.Windows.Interactivity.dll, and since it also wrote a library, a small program needs to be accompanied by 3 DLLs, this body Really uncomfortable, so I started to embed the DLL into the EXE.
Setbacks
For C # programs, to embed the DLL into the EXE, the most authoritative and most common method is to use ilmerge this tool, this is a command line tool, there are many parameters, you can put the DLL is perfectly embedded into the EXE, if the command line trouble, Also someone open source developed the graphical interface Ilmergegui, the download and help address of these two tools are as follows:
- Ilmerge http://www.microsoft.com/en-us/download/details.aspx?id=17630
- Ilmerge-gui http://ilmergegui.codeplex.com/
So downloaded the two tools, but the DLL embedded in the EXE in the case of the error, in the online search for the next reason, unexpectedly is ilmerge not support WPF program, I le a go, Microsoft, you let me say you what good?
Ilmerge can embed the DLL of the WinForm program into the EXE (which I personally tested, very little, like), but not for WPF, because the WPF DLL contains resources that cannot be resolved, Microsoft, do you have the nerve to say that this tool was developed by you?
WinForm program embeds DLLs into EXE (one)--using the command line
Download Ilmerge or download Ilmerge-gui at the same time, using the graphical interface and using the command line is the same, but the graphical interface is simple, so here is the command line description.
I downloaded ilmerge after the installation, the ILMerge.exe copied to the C:\Windows directory, so that can be used directly on the command line without setting the environment variables, anyway, as long as the command line can be used to use the tool on the line.
Ilmerge has many parameters, several of which are more important:
- /target: target, there are library and winexe two options, when multiple DLLs are integrated into a DLL can use the library, when you want to integrate as EXE, you should use the winexe.
- /out: output, the path and name of the resulting file.
- /log: Input, if the input is EXE can not use this parameter to write directly, and if the input-time DLL, it is best to use this parameter
There are some other parameters, you can use Baidu or Google, this is a picture of my test:
The WinForm program embeds the DLL in the EXE (ii)--Using the ILMerge.MSBuild.Tasks
Ilmerge also uses NuGet to publish tools, and the benefits of using NuGet must be known to everyone, so this approach is recommended .
The first step is to download ILMerge.MSBuild.Tasks using NuGet graphics or NuGet commands
PM> Install-Package ILMerge.MSBuild.Tasks
The second step is to open the VS project file Notepad or other text editing tools, I use sublime text 3, and according to the following format to modify the actual situation:
<!-- 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" /> <!-- 这儿改成需要做嵌入的dll名 --> <MergeAsm Include="$(OutputPath)LIB2_To_MERGE.dll" /> </ItemGroup> <PropertyGroup> <MergedAssembly>$(ProjectDir)$(OutDir)MERGED_ASSEMBLY_NAME.exe</MergedAssembly><!-- 这儿改成需要做输出的exe名 --> </PropertyGroup><Message Text="ILMerge @(MergeAsm) -> $(MergedAssembly)" Importance="high" /><ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" /></Target>
This will be done after compiling.
WPF program embeds DLLs into EXE (one)--converts DLLs to embedded resources automatically
The first step is to modify the project file to automatically convert the DLL to an embedded resource.
Open the VS project file Notepad or other text editing tool, I'm using sublime text 3 and add the following to the end of the file:
<Target Name="AfterResolveReferences"> <ItemGroup> <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'"> <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName> </EmbeddedResource> </ItemGroup></Target>
The second step is to modify the App.xaml file to load the resource when the program starts
Public partial class app:application{private static Assembly onresolveassembly (object sender, Resolveeventargs args) {Assembly executingassembly = assembly.getexecutingassembly (); var executingassemblyname = Executingassembly.getname (); var resname = Executingassemblyname.name + ". Resources"; AssemblyName assemblyname = new AssemblyName (args. Name); String path = ""; if (Resname = = assemblyname.name) {path = Executingassemblyname.name + ". G.resources";; } else {path = Assemblyname.name + ". dll"; if (assemblyName.CultureInfo.Equals (cultureinfo.invariantculture) = = False) {Path = String.form at (@ "{0}\{1}", Assemblyname.cultureinfo, Path); }} using (Stream stream = Executingassembly.getmanifestresourcestream (path)) {if (stream = = NULL) return null; byte[] Assemblyrawbytes = new Byte[streAm. Length]; Stream. Read (assemblyrawbytes, 0, assemblyrawbytes.length); Return Assembly.Load (assemblyrawbytes); }} protected override void Onstartup (StartupEventArgs e) {base. Onstartup (e); AppDomain.CurrentDomain.AssemblyResolve + = onresolveassembly; }}
Third step, DLL embedded EXE, DLL in the directory is useless, configure the post BUiD script to automatically delete the DLL:
cd $(TargetDir)del *.dll
In some cases, the above method is not possible, then you can try Eazfuscator.net
Eazfuscator.net used to be free, now it has become a fee software, but to find a free version of 3.3 can also support VS2010 and VS2012
WPF program embeds DLLs into EXE (ii)--using Libz Container
LIBZ is another option for ilmerge, it can also embed the DLL into the EXE, in my test it can complete the WPF program DLL embedded into the EXE, but it seems that this component uses not many people.
LIBZ Container's Project homepage is http://libz.codeplex.com/
LIBZ also offers NuGet downloads, and there are many benefits to using NuGet, so this is the recommended approach .
Download Libz.bootstrap using NuGet graphics or commands
Install-Package LibZ.Bootstrap
Then, configure the post BUiD script:
set LIBZ=$(SolutionDir)packages\LibZ.Bootstrap.1.1.0.2\tools\libz.exe%LIBZ% inject-dll --assembly VSConverter.WPF.exe --include *.dll --move
After the compilation has passed, you can. It is important to note that the parameter after--assembly is the file name generated by the project .
LIBZ also has many uses that can be learned in project documentation.
Resources
- Combining multiple assemblies to a single EXE for a WPF application
- DLL embedded in EXE
- LIBZ Project
NuGet is a very powerful tool, and using NuGet can be a great way to make the solution simple and to praise NuGet!
To do another ad, the Visual Studio version Conversion tool for the WPF version of the code hosting address is: Http://git.oschina.net/shupengluo/VSConverter, Welcome to Exchange.
Finally, a little contempt for the next Microsoft, ^_^
Two ways that a WPF program embeds DLLs into an EXE