我怎么可以嵌入包含在一个dll到一个EXE组件,以便它可以从内存中运行? [英] How can I embed components contained in a dll into an exe so it can be run from memory?

查看:159
本文介绍了我怎么可以嵌入包含在一个dll到一个EXE组件,以便它可以从内存中运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让必须从内存中运行的程序(通过的Assembly.Load(箱)所描述的这里)(仅供参考) .dll文件。

I am trying to make a program that must be run from memory (through Assembly.Load(bin) as described here) using custom components sitting in a (referenced) .dll.

由于运行从内存中的code运行一个.exe,如何组件嵌入使得.dll文件是没有必要的。exe?

Since the run-from-memory code runs an .exe, how can the components be embedded in the .exe such that the .dll isn't needed?

我已经试过ILMerge,但由此产生的.exe文件将不会从内存中运行。 我看<一href="http://blogs.msdn.com/b/microsoft_$p$pss/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx"相对=nofollow>这个,但我不认为它的​​工作原理,如果你引用的.dll文件(我不得不因为它包含在我的表单组件)

I've tried ILMerge, but the resulting .exe wouldn't run from memory. I've looked at this but I don't think it works if you've referenced the .dll (which I had to because it contains components on my form)

更新

在读NSGaga的回答,我试过如下:

Having read NSGaga's answer, I tried the following:

  • 设置组件.dll文件包括在项目是嵌入的资源
  • 作了除了的Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace MyApp
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {            
            AppDomain.CurrentDomain.AssemblyResolve +=
            (sender, args) =>
            {
                // System.Diagnostics.Debugger.Break();
                String resourceName = "MyApp." +

                    new AssemblyName(args.Name).Name + ".dll";

                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                {

                    Byte[] assemblyData = new Byte[stream.Length];

                    stream.Read(assemblyData, 0, assemblyData.Length);

                    return Assembly.Load(assemblyData);

                }

            };
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

不幸的是,这并不工作,我得到一个 FileNotFoundException异常

Unfortunately this doesn't work, I get a FileNotFoundException:

无法加载文件或程序集MetroFramework,版本= 1.2.0.0,文化=中性公钥= 5f91a84759bf584a或它的某一个依赖。该系统找不到指定的文件。

Application.Run(新的MainForm())发生的异常; 行。此外,有breakpointed /加消息框等等,我不相信 AssemblyResolve 处理程序不断被称为 - ?我在做什么错

The exception occurs on the Application.Run(new MainForm()); line. Also, having breakpointed/added message boxes etc, I don't believe the AssemblyResolve handler is ever being called - what am I doing wrong?

推荐答案

您已经回答了pretty的多 - 这手动解决方案从杰弗里里希特应该只是罚款 - ILMerge有问题(如WPF)。

You already answered that pretty much - that manual solution from Jeffrey Richter should work just fine - ILMerge has issues (e.g. WPF).

这是因为我打得瓦特/一个很长一段时间,但这是rougly你需要做的......

it was a long time since I played w/ that but this is rougly what you need to do...

1)prepare您的应用程序了一下 - 这意味着 - 你可以不加载任何东西,直到你设置你的 AssemblyResolve 处理程序。这也意味着任何东西是如从'主'称为(甚至之后)将必须'解决'之前。总之,将你需要'引用'一些'后'code一切,

1) Prepare your app a bit - meaning - you cannot load anything until you setup your AssemblyResolve handler. That also means anything that is e.g. called from 'main' (even afterwards) will have to be 'resolved' before. In short, move everything you need 'referenced' to some 'later' code,

2)添加处理程序 - 尽快。我就再说一遍,里希特的codeW /一些信息。另外看看在 http://support.microsoft.com/kb/319292

2) Add the handler - as soon as possible. I'll just repeat that Richter's code w/ some info. Also take a look at the http://support.microsoft.com/kb/319292.

AppDomain.CurrentDomain.AssemblyResolve +=
(sender, args) =>
{
    // System.Diagnostics.Debugger.Break();
    // Lookup what's your namespace in project properties
    String resourceName = "YourAssemblyNamespace." +
        new AssemblyName(args.Name).Name + ".dll";
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
==>
        if (stream == null)
            return null;
==>
        Byte[] assemblyData = new Byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }
};

3)进行测试 - 将你的'负荷'LIB code上的一些咔嗒或东西 - 并把一个休息(像我一样),

3) To make a test - move your 'loading' lib code on some 'click' or something - and put a 'Break' (like I did),

4)添加您的DLL-S'为嵌入的资源 - 即就像BMP或什么的,在根。添加外部文件 - 然后将它的属性是嵌入的资源。

4) Add your dll-s `as embedded resources' - i.e. just like bmp or something, in the root. Add external file - then set it in properties to be 'embedded resources'.

5)构建的应用程序 - 并注意大小的变化,应该是pretty的多少在DLL-S的区别,

5) Build the app - and notice the change in size, should be pretty much the difference in dll-s,

6)去你的bin目录 - 并删除DLL-S。不要再建项目,并从VS /调试离开,

6) go to your bin dir - and remove dll-s. Don't build the project again and move away from the VS/Debugger,

7)启动应用程序并观察...

7) start the app and observe...

注意: 你可能会得到异常(如LIB你暗示) - 你需要处理,如果流== NULL。 问题是各种DLL-S的往往是试图加载(或从应用程序请求的),他们安全的失败 - 因为我们添加'处理',我们有责任轻声没有以同样的方式。请参阅编辑code以上。

NOTE: You may get exceptions (like the lib you're suggesting) - you need to handle if stream==null. 'Problem' is that all sorts of dll-s are often 'attempted to be loaded (or requested from the app) and they safe fail - since we add the 'handler' we're responsible for softly failing in the same way. See the edited code above.

您code编辑:

您可能需要移动开始了一下后点窗口 - 你检查的处理程序被调用(断点和所有 - 做一些痕迹太)。

You may need to move the window starting at a bit later point - have you checked that handler is called (breakpoint and all - do some trace too).

问题是,主窗口的决议,尽快开始为它变得可见 - 即在主要 - 这种情况发生之前实际code运行或处理程序设置。所以......

Problem is that the MainWindow resolution begins as soon as it gets visible - i.e. in the Main - and that happens before the actual code runs or handler is set up. So...

static void Main(){
    ...
    DoAppSetup();
    // Application.EnableVisualStyles();
    // Application.SetCompatibleTextRenderingDefault(false);
    // Application.Run(new MainForm());
}
static void DoAppSetup(){
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}

...这样,您的处理程序应设置任何东西之前,甚至尝试解决。

...that way your handler should be set up before anything even tries to resolve.

这篇关于我怎么可以嵌入包含在一个dll到一个EXE组件,以便它可以从内存中运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆