WPF程序将DLL嵌入到EXE的两种方法
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
WPF程序?qū)LL嵌入到EXE的兩種方法
這一篇可以看作是《Visual Studio 版本轉(zhuǎn)換工具WPF版開(kāi)源了》的續(xù),關(guān)于《Visual Studio 版本轉(zhuǎn)換工具WPF版開(kāi)源了》可以參看地下地址(兩篇是一樣的):
引言
前幾一寫了一個(gè)小工具————《Visual Studio版本轉(zhuǎn)換工具》,由于使用了WPF做為界面,因此這個(gè)小程序運(yùn)行必須附帶兩個(gè)DLL:Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll,同時(shí)由于自己也寫了一個(gè)庫(kù),一個(gè)小程序需要附帶3個(gè)DLL,這種體驗(yàn)真的很不爽,于是就著手把DLL嵌入到EXE中去。
挫折
對(duì)于C#程序,要把DLL嵌入到EXE中去,最權(quán)威和最常見(jiàn)的方法就是使用ILMerge這個(gè)工具,這是個(gè)命令行工具,有很多參數(shù),可以將DLL很完美的嵌入到EXE中去,如果嫌命令行麻煩,也有人開(kāi)源開(kāi)發(fā)了圖形界面ILMergeGUI,這兩個(gè)工具的下載和幫助地址如下:
于是下載了這兩個(gè)工具,卻出現(xiàn)將DLL嵌入到EXE中錯(cuò)誤的情況,在網(wǎng)上查了下原因,竟然是ILMerge不支持WPF程序,我勒了個(gè)去,微軟,你讓我說(shuō)你什么好呢?
ILMerge可以將Winform程序的DLL完美地嵌入到EXE中去(這一點(diǎn)我親自測(cè)試了下,很不,點(diǎn)贊),但對(duì)WPF卻不支持,原因是WPF的DLL中含有資源無(wú)法解決,微軟,你好意思說(shuō)這個(gè)工具是你開(kāi)發(fā)的嗎?
Winform程序?qū)LL嵌入到EXE中(一)——使用命令行 ##
下載ILMerge或者同時(shí)下載ILMerge-GUI,使用圖形界面和使用命令行是同一個(gè)道理,只是圖形界面簡(jiǎn)單些,所以這里以命令行說(shuō)明。
我是下載ILMerge安裝后,把ILMerge.exe復(fù)制到C:\Windows目錄下去了,這樣可以直接在命令行中使用而不用去設(shè)置環(huán)境變量,不管怎樣,只要能夠在命令行下使用這個(gè)工具就行。
ILMerge有很多參數(shù),其中有幾個(gè)比較重要:
還有其它一些參數(shù),使用時(shí)可以百度或者google一下,這是我測(cè)試的一張圖片:
Winform程序?qū)LL嵌入到EXE中(二)——使用ILMerge.MSBuild.Tasks
ILMerge也使用Nuget發(fā)布了工具,使用Nuget的好處想必大家都知道,所以推薦使用這種方法。
第一步, 使用Nuget圖形或Nuget命令下載ILMerge.MSBuild.Tasks
第二步, 把VS項(xiàng)目文件記事本或者其它文本編輯工具打開(kāi),我使用的是Sublime Text 3,并按照如下格式根據(jù)實(shí)際情況修改:
<!-- 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>這樣編譯后就可以了。
WPF程序?qū)LL嵌入到EXE中(一)——將DLL自動(dòng)轉(zhuǎn)換為嵌入資源
第一步,修改項(xiàng)目文件,將DLL自動(dòng)轉(zhuǎn)換為嵌入資源。
把VS項(xiàng)目文件記事本或者其它文本編輯工具打開(kāi),我使用的是Sublime Text 3,并將下面內(nèi)容添加到文件末尾:
第二步,修改App.xaml文件,在程序啟動(dòng)時(shí)加載資源
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.Format(@"{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;} }第三步,dll嵌入exe后,目錄中的dll就沒(méi)用了,配置Post buid 腳本自動(dòng)刪除dll:
cd $(TargetDir) del *.dll有些情況下,以上方法也不行,那么可以嘗試 Eazfuscator.NET Eazfuscator.NET以前免費(fèi),現(xiàn)在已經(jīng)變成收費(fèi)軟件了,不過(guò)找個(gè)免費(fèi)的3.3版本也可以支持VS2010和VS2012
WPF程序?qū)LL嵌入到EXE中(二)——使用LibZ Container
LibZ是ILMerge的另外一個(gè)選擇,它同樣可以把DLL嵌入到EXE中去,在我的測(cè)試中它可以完成WPF程序的DLL嵌入到EXE中去,但好像這個(gè)組件使用的人不是很多。 LibZ Container的項(xiàng)目主頁(yè)是http://libz.codeplex.com/
LibZ同樣提供了Nuget下載,使用Nuget有很多好處,所以推薦使用這種方式。
使用Nuget圖形或者命令下載LibZ.Bootstrap
然后,配置Post buid 腳本:
set LIBZ=$(SolutionDir)packages\LibZ.Bootstrap.1.1.0.2\tools\libz.exe %LIBZ% inject-dll --assembly VSConverter.WPF.exe --include *.dll --move編譯通過(guò)后就可以了。這里需要注意的是--assembly后的參數(shù)是項(xiàng)目生成的文件名. LibZ還有很多用法,可以到項(xiàng)目文檔學(xué)習(xí)。
參考資料
Nuget是個(gè)十分強(qiáng)大的工具,使用Nuget在很多時(shí)候可以使解決方法變得簡(jiǎn)單,給Nuget贊一個(gè)!
再做下廣告,Visual Studio版本轉(zhuǎn)換工具WPF版的代碼托管地址是:http://git.oschina.net/shupengluo/VSConverter,歡迎交流。
最后,再小小地鄙視下微軟,^_^
轉(zhuǎn)載于:https://my.oschina.net/chinesedragon/blog/309223
總結(jié)
以上是生活随笔為你收集整理的WPF程序将DLL嵌入到EXE的两种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 怀孕梦到捉鱼预示着什么
- 下一篇: oracle文件