1) 利用NUGet下载 ILMerge.MSBuild.Tasks
PM> Install-Package ILMerge.MSBuild.Tasks
2)把VS项目文件打开,用记事本 编辑
<!-- 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> </PropertyGroup> <Message Text="ILMerge @(MergeAsm) -> $(MergedAssembly)" Importance="high" /> <ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" /> </Target>
3) 可惜以上的配置不支持WPF,若要实现WPF嵌入dll,参考如下:
首先,修改项目文件.csproj,使所有dll自动嵌入为资源文件(加到项目文件最后即可):
<Target Name="AfterResolveReferences"> <ItemGroup> <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'"> <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName> </EmbeddedResource> </ItemGroup> </Target>
然后,在App.xaml中加入如下代码:
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就没用了,配置Post buid 脚本自动删除dll:
cd $(TargetDir)
del *.dll
4) 有些情况下,以上方法也不行,那么可以尝试 Eazfuscator.NET
Eazfuscator.NET以前免费,现在已经变成收费软件了,不过找个免费的3.3版本也可以支持VS2010和VS2012