2

i am trying to include a dll within the compiled exe so that i don't need to dispatch the dll with the exe.I have seen many answers but non of them worked for me! I have added the dlltest.dll to "Reference" and modified "copy local" to False. I aslo added it to the project tree and modified the "build action" to embedded resource" (In Visual Studio)

the dlltest.cs code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dll
{
    public class Class1
    {
        public int sum(int a, int b)
        {
            int c = a + b;
            return c;
        }
    }
}

the app.cs code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace Myapp
{
    public class Loader
    {
        static void Main(string[] argss)
        {
            netsum thisapp = new netsum();  
        }
        public class netsum
        {
            public netsum()
            {
                dlltest.Class1 c = new dlltest.Class1();
                Console.WriteLine(c.sum(3, 10));
                Console.ReadKey();
            }
        }
    }
}

thanks!

Xaruth
  • 4,034
  • 3
  • 19
  • 26
  • 4
    Probable duplicate of [this](http://stackoverflow.com/questions/189549/embedding-dlls-in-a-compiled-executable) – Jazzy J Oct 10 '13 at 15:40

4 Answers4

2

Assuming you want to use the EmbeddedResource approach, rather than ILMerge, the last step you need is to make your assembly available during the execution of your program:

static Assembly embedded_assembly;

static void Main(string[] argss)
{
    embedded_assembly = LoadEmbeddedAssembly("empty_vs_project", "embedded-dll.dll");
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    netsum thisapp = new netsum();
}

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name == embedded_assembly.FullName)
        return embedded_assembly;
    return null;
}

public static Assembly LoadEmbeddedAssembly(string resourceNamespace, string assemblyName)
{
    var assemblyBytes = GetEmbeddedResource(resourceNamespace + "." + assemblyName);
    return AppDomain.CurrentDomain.Load(assemblyBytes);
}

public static byte[] GetEmbeddedResource(string resourceName)
{
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
        var bytes = new byte[stream.Length];
        stream.Read(bytes, 0, (int)stream.Length);
        return bytes;
    }
}

Things to note here:

  • the dll in questions is called "embedded-dll.dll", and I have added it as a link item to the VS project to ensure we always embed the latest version - with an EmbeddedResource action, just like you are doing (see here for adding project items as links)

  • the project name of the executable is "empty_vs_project", which is also the resource namespace for GetManifestResourceStream

  • the code used the AppDomain.AssemblyResolve event which requires that your application have a certain level of permissions; if that is not the case, you could simply extract the assembly into AppDomain.BaseDirectory and let the assembly loader find it there (this requires write permissions for the directory though.

HTH!

staafl
  • 3,147
  • 1
  • 28
  • 23
  • @user2867701, I just tested it and the approach works, but the code is a bit different. I'll edit my answer in a minute. – staafl Oct 11 '13 at 09:18
  • how can i use it to call more than one dll though? – user2867701 Oct 11 '13 at 14:16
  • why, simply embed them into the project, `LoadEmbeddedAssembly` them into static variables and add them to the `CurrentDomain_AssemblyResolve` handler, just like we have done with this one. – staafl Oct 11 '13 at 14:23
  • hi, I have two DLLs where DLL (A) has referenced DLL (B) during the build of DLL (A). now for the APPLICATION (C) I am using both DLLS (A+B). I have embedded the two DLLS within the EXE of APPLICATION (C), but it keeps failing because DLL (A) still is referencing DLL (B). i tried to embbed DLL (A+B) but still didn't work. any ideas? many thanks for your help! – user2867701 Nov 08 '13 at 19:02
  • @user2867701, try replacing Assembly.GetExecutingAssembly() with Assembly.GetEntryAssembly() to make sure you're always reading the embedded dlls from the right place (executable C). – staafl Nov 09 '13 at 08:33
  • I'm afraid that's not specific enough for me to help you. The setup should work (A and B embedded separately in C, with the appropriate modifications to the code above). For me to be able to help you, you'll need to show me the code you're using, or even better, prepare a small sample project that demonstrates the issues you're having. – staafl Nov 11 '13 at 16:34
  • I will try few use cases first before bothering you :) but i now need to embbed a c++ dll into the c# assembly. i looked at how to embbed native dlls into c# and they are different than the managed dlls. not have any luck yet. do u have any idea? many thanks. – user2867701 Nov 12 '13 at 08:46
  • hi, just to confirm, the dll that i want to embbed is managed c++ dll. thanks. – user2867701 Nov 12 '13 at 09:50
  • @user2867701, this is an entirely separate scenario, and you will probably need to extract the native dll to your application directory at runtime for the PInvoke to work. If you want help with that, please open a new question and send me a link to it. – staafl Nov 12 '13 at 19:53
  • regarding embedding two dlls (in which one reference the other) into an exe, please find below an example: – user2867701 Nov 20 '13 at 11:03
  • firest dll: namespace dll_test1 { public class test1 { public int add(int a) { dll_test2.test2 x = new dll_test2.test2(); int c = a + x.subtract(20,10); return c; } } } -- second dll: namespace dll_test2 { public class test2 { public int subtract(int a, int b) { int c = a - b; return c; } } } ---------------- – user2867701 Nov 20 '13 at 13:30
  • application: namespace apptest { class Program { static void Main(string[] args) { netsum thisapp = new netsum(); } public class netsum { public netsum() { dll_test1.test1 c = new dll_test1.test1(); dll_test2.test2 b = new dll_test2.test2(); int x = c.add(10)+ b.subtract(20,10); Console.WriteLine(x); Console.ReadKey(); } } } } – user2867701 Nov 20 '13 at 13:31
  • sorry, i didn't know how to put the code in the right format way! – user2867701 Nov 20 '13 at 14:18
  • hi just wondering if you managed to look at the code to embed two dlls in the exe? thanks for your time. – user2867701 Jan 06 '14 at 14:28
1

ILMerge should work for you (a utility that can be used to merge multiple .NET assemblies into a single assembly): http://www.microsoft.com/en-us/download/details.aspx?id=17630

Yosi Dahari
  • 6,794
  • 5
  • 24
  • 44
0

You can use the tool ILMerge to merge the EXE and the DLL into a single assembly:
http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx
Download page:
http://www.microsoft.com/en-us/download/details.aspx?id=17630

ProgramFOX
  • 6,131
  • 11
  • 45
  • 51
0

I suggest Red Gate's SmartAssembly.

It can do that along with many other extremely useful operations like:

  • Compressing
  • Merging
  • Encrypting
  • Pruning (remove unused code from executable)
  • Obfuscating
  • Automated error reporting
  • More

I thoroughly enjoy it.

Note that unfortunately it's not free, and can sometime mess with your builds but it lets you debug these cases. You can just use simple operations where stuff are less likely to get messed up of course.

MasterMastic
  • 20,711
  • 12
  • 68
  • 90