我經常寫小工具程式,不用安裝程式,單一EXE檔隨Copy隨用是最理想的部署設計。不過,程式稍稍複雜就難免依功能屬性拆分多個專案,有時需用到跨專案的共享程式庫,至於引用Json.NET、Dapper、NLog等必備套件的情況更是普遍。例如以下專案,Tool為Console Application(EXE)專案,引用Model類別程式庫專案,還參考了Json.NET:
編譯後會產生三組組件檔:Tool.exe、Model.dll與Newtonsoft.Json.dll,得一起部署到客戶端才能正確執行。
要實現單一EXE檔搞定,.NET有個好用工具-ILMerge,可將多個DLL、EXE檔合併成單一檔案(ILMerge使用方式可參考保哥的介紹文),原本想花點時間研究怎麼安排AfterPost事件執行ILMerge,驚喜地發現已有好心人包成MSBuild的Task!
在NuGet使用msbuild.ilmerge查詢,可以找到MSBuild.ILMerge.Task,二話不說,安裝到專案。
安裝後專案會多出ILMerge.props、ILMergeOrder.txt,但大部分情況下不需修改,直接編譯就好。
重新編譯可發現Model.dll及Newtonsoft.Json.dll不見了,只剩一個變胖的Tool.exe,使用時只需Copy這個檔案就行了。
用JustDecompile解析,可以看到Tool.exe裡藏了Model跟Newtonsoft.Json組件裡的所有型別。
用這種做法即可輕鬆一檔搞定小工具程式的部署,非常方便。
補充:MSBuild.ILMerge.Task預設會將參照到的DLL都包進EXE檔,如果想略過特定DLL,可將DLL的Copy Local屬性設為False即可排除。