C # 4.0 Fusionar ensamblado .dll con .NET

I decided to leave my otra pregunta to die, since I thought of a new idea using Jeffrey Richter's method written on consulta en esta página to merge a .dll library to my application. So I added my .dll file as an embedded resource and also added it as a reference. Then in Program.cs (I have no idea where the code he posted is supposed to go), I added this:

    ...
    [STAThread]
    static void Main()
    {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length > 1)
                _in = args[1];
            SingleInstanceController controller = new SingleInstanceController();
            controller.Run(args);

            AppDomain.CurrentDomain.AssemblyResolve += (sender, argsx) =>
{
String resourceName = "AssemblyLoadingAndReflection." +
   new AssemblyName(argsx.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);
    }
}
        ;

Am I supposed to change resourceName to something else? Have I added it correctly (in the right place)?

Now the problem is, it still fails to find and load the assembly and I'm not sure what I've done wrong. Any help would be appreciated.

preguntado el 09 de enero de 11 a las 06:01

Just curious; why even bother to (effectively) statically link a DLL? -

Because I don't want to distribute my program will 10-15 files the user finds useless. -

Why is the user digging around in program files anyway? Just install them into a sub-directory and be done with it. I mean, the "DL" in "DLL" stands for "Dynamic Link" you know. -

3 Respuestas

Hook to the AssemblyResolve event before the AppDomain tries to resolve references i.e in the entry point and the first line.

The embedded resource name starts with the application name followed by the resource name. ex: ConsoleApplication.Test.dll.

Respondido el 09 de enero de 11 a las 10:01

I'm not quite sure what you mean by your first line, could you explain? (Sorry I'm kind of new to C# and don't have much experience). - Iceyoshi

Move the AppDomain.CurrentDomain.AssemblyResolve += .... to the first line in Main method. - Vijay Sirigiri

I get this error: "Could not load file or assembly 'Files, Version=2.3.4025.2210, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER))" when I do that, and rename my resource name. - Iceyoshi

replace String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(argsx.Name).Name + ".dll"; with String resourceName = String.Format("MyApp.{0}", args.Name); - Vijay Sirigiri

The error still remains, even when I added String resourceName = String.Format("MyApp.{0}", args.Name) + ".dll"; too. It's definitely indicating that it can't find the assembly but I can't think of any reason why it would do that. I added a reference to that file and also embedded it and moved the code to the first line as you stated. - Iceyoshi

Your problem is very similar to this one: C #: Cómo incrustar DLL en el archivo de recursos (sin copia dll en el directorio del programa)

Básicamente, tu AppDomain.AssemblyResolve event handler did not get called because Main failed to compile. Even if it did compile, attaching the event handler should be the first thing you do in main.

My answer to the question above has a working code sample and explanation on why your code does not work.

contestado el 23 de mayo de 17 a las 15:05

Use the debugger. Set breakpoints on the AssemblyResolve assignment and the lambda body. Single step the code.

Yes, that's too late. Move the assignment. If SingleInstanceController is in such a DLL then the Main() method never even gets started. Move that code into a separate helper method and give it the [MethodImpl(MethodImplOptions.Noinlining)] attribute.

Distributing your program in a single file is already very well supported, it doesn't require any code nor merging DLLs. Also takes care of the desktop shortcut, the file associations and getting .NET installed on old machines. It's called setup.exe

Respondido el 09 de enero de 11 a las 10:01

Yeah, thanks for totally ignoring my question. I asked why my code wasn't working or what I was doing wrong, not "should I distribute .dll files with my application or not". I have my reasons for not distributing the .EXE file with a bunch of .dll files. Also, where did setup.exe come from? My application is a relatively small and portable one and I don't even want to use that. - Iceyoshi

I didn't ignore your question, you ignored the answer. Do try to read more than just the last paragraph. You won't get the perfect answer until you debug your problem. - Hans Passant

"until you debug your problem" <- which I needed help with, hence I asked here. You are right in the sense I ignored your first paragraph though. - Iceyoshi

Is the issue that you don't know how to use the debugger? What did happen when you single stepped the program? I gave the answer but you can't see it in front of your eyes until you try this. - Hans Passant

"I avoid using the debugger as much as possible". I can't believe i just read that... - Phill

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.