2

I am making an application which is almost done but there is one thing that is bugging me. There are about 12-13 files that must be in the directory of the folder (some .dlls, some .xml files etc.) for the application to run, and I want to make my application as compact as possible, meaning I want as fewer files to go with the application. So my question is, how can I do this? Can all the files be included in the application itself? Is it necessary for the .dlls to be in the application folder or can I reference them from somewhere else? I was thinking to make a folder for all those files but I don't think my application will run if a .dll file isn't placed in the same directory as the application.

jball
  • 24,791
  • 9
  • 70
  • 92
david
  • 357
  • 2
  • 7
  • 18
  • 1
    If you go to your profile page, you'll see a number of questions without accepted answers. (The ones with the number of answers in white as opposed to yellow). In each of those questions, click the hollow check next to the most helpful answer. – SLaks Nov 12 '10 at 03:58

2 Answers2

2

You can handle the AppDomain.AssemblyResolve event and call Assembly.Load(path) to load DLLs from non-standard folders.

You can even call Assembly.Load(byte[]) to load a DLL that is embedded in your EXE as a resource.

Note that the JITter will load all types used by a method before the method starts executing (in order to compile the method).
Therefore, you must add the event handler before using any methods or types in the DLLs, and the method that adds the handler cannot directly use the DLLs.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Thanks for the information! I haven't played with the AssemblyResolve events yet, but I now see what my weekend project is going to be. :-) – Larry Smithmier Nov 12 '10 at 04:15
0

How to embed and access resources by using Visual C# looks like just what you need.
[edit] If you want to load DLLs, you can combine the above with the AppDomain.AssemblyResolve event SLaks mentions like this:

using System.IO;
using System.Reflection;

namespace ConsoleApplication3
{
  class Program
  {
    static void Main(string[] args)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += 
                new ResolveEventHandler(MyResolveEventHandler);
        var myWrappedClass1 = 
            currentDomain.CreateInstance(
                    "ConsoleApplication3.ClassLibrary1.dll", 
                    "ClassLibrary1.Class1");
        var myClass1 = myWrappedClass1.Unwrap();
        Console.WriteLine(myClass1.GetType().InvokeMember(
                    "Add", 
                    BindingFlags.Default | BindingFlags.InvokeMethod, 
                    null,
                    myClass1, 
                    new object[] { 1, 1 }));
        Console.ReadLine();
    }

    private static Assembly MyResolveEventHandler(
            object sender, ResolveEventArgs args)
    {
        Assembly currentAssembly=null;
        Stream dllStream;
        try
        {
            currentAssembly = Assembly.GetExecutingAssembly();
            dllStream = 
                    currentAssembly.GetManifestResourceStream(args.Name);
            var length = (int)dllStream.Length;
            var dllByteArray = new byte[length];
            int bytesRead;
            int offset = 0;
            while ((bytesRead = dllStream.Read(
                                    dllByteArray, 
                                    offset, 
                                    dllByteArray.Length - offset)) 
                    > 0)
                offset += bytesRead;
            return Assembly.Load(dllByteArray);
        }
        catch
        {
            Console.WriteLine("Error accessing resources!");
        }
        return null;
    }
  }
}

where Class1 is a class library containing just:

namespace ClassLibrary1
{
    public class Class1
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

and the DLL is added as an Embedded Resource to the file:

alt text alt text

Larry Smithmier
  • 2,711
  • 2
  • 23
  • 30
  • If the example they give isn't current enough, let me know what .NET version you are developing in and I will get you some sample code. – Larry Smithmier Nov 12 '10 at 03:57
  • Can you also do this with .DLL files? I did know you can embed resources this way but there is nothing shown in the properties when you right-click and select properties of a .dll file. Also, I am using .NET Framework 4.0 – david Nov 12 '10 at 04:21
  • Hello David, please let me know if this example makes it clearer. – Larry Smithmier Nov 13 '10 at 02:46