微軟有一個工具叫ILMerge可以合並dll exe等,但是對於wpf的應用程序而言這個工具就不好用了。我的這方法也是從國外一個博客上找來的。僅供大家參考。
第一步:把下面的代碼寫到你的項目文件的標准的Microsoft.CSharp下面,也就是.csproj的文件里
<Target Name="AfterResolveReferences">
<ItemGroup>
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>
第二步:把你需要引用的dll復制到你當前項目的Resources文件夾下面,並把他們作為嵌入式資源(dll的屬性里有此設置),為了避免文件名沖突,把這些dll的后綴加上 resources (System.Windows.Interactivity.resources.dll)
第三步:通常WPF應用程序包含一個xaml文件,它充當一個神奇的入口點到應用程序和啟動的第一個窗口。然而,xaml其實沒那么神奇。如果你仔細看一下這些文件夾在您的項目文件夾obj,你會發現一個appg.cs文件,這是來自你的xaml。它包含一個正常的“靜態空隙主要“c#入口點所以為了得到在WPF之前,所有您需要做的就是定義自己的入口點進入一個新類,做你需要,然后調用正常WPF入口點。添加一個類Program.cs並把它設置成程序的入口點。
第四步:構建Program.cs的代碼
public class Program
{
[STAThreadAttribute]
public static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
App.Main();
}
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
AssemblyName assemblyName = new AssemblyName(args.Name);
string 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);
}
}
}
簡單的四步,如果引用的dll中的版本有低於當前項目版本的話會有錯誤,我是直接把這個dll拿出來和合並后的exe放在一起了。或者把當前引用的dll版本統一掉。出現此問題最多的時候是引用的第三方的dll。
原文地址:http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application
