在win app和C#中嵌入所有DLL

时间:2012-09-01 07:55:23

标签: c# dll embed exe

我使用此代码将所有dll嵌入到app exe文件中,但此代码只能嵌入一个dll。我搜索其他代码,但都是相同的。

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");

    dllName = dllName.Replace(".", "_");

    if (dllName.EndsWith("_resources")) return null;

    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());

    byte[] bytes = (byte[])rm.GetObject(dllName);

    return System.Reflection.Assembly.Load(bytes);
}

使用ILmerge我有问题wuth我的dll。所以我不能用这个。 我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:0)

这个开源工具应该可以帮到你

http://madebits.com/netz/

答案 1 :(得分:0)

一种可能的方法是将所有DLL添加到资源(手动)。然后,在程序启动时,使用File.WriteAllBytes将这些资源字节流写入文件。

注意:在这种情况下,您无法使用DllImport,因为它需要常量字符串路径。相反,您将使用所谓的“动态P \ Invoke”。 Learn more.

答案 2 :(得分:0)

使用GetManifestResourceStream可以更好地工作。

当dll作为资源嵌入时,资源名称以项目的默认名称空间为前缀,因此您需要填充它。

例如

static  System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string defaultNameSpace = "...";

    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");

    string resourceName = String.Format("{0}.{1}.dll", defaultNameSpace , dllName);

    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
         if (stream == null)  
             return null;

         byte[] data = new byte[stream.Length];
         stream.Read(data, 0, data.Length);
         return Assembly.Load(data);
     }
 }