The problem: I have an executable and mylib.dll (C# class library) in the same directory. I have a subdirectory "Patch" in that directory containing another version of that mylib.dll. I need to make a sample application somehow that loads the first dll, than frees it (like LoadLibrary and FreeLibrary in Windows API, but here I use Domain.Load, Domain.Unload), and then loads another version of that dll from "Patch" folder.
Problems:
1) when I try to load the library from "Patch" directory, the library from the application directory is loaded (even if I add some other paths to domain),
2) if I rename "Patch\mylib.dll" to "Patch\mylib1.dll" and try to load the second, renamed one, it is anyway resolved to its original name and again - assembly from mylib.dll in application directory is loaded,
3) if I unload (free) mylib.dll, delete it from my computer, move "Patch\mylib.dll" to "mylib.dll", load it....... I anyway get the original dll that I deleted... it seems like there is hash,
4) changing "patched" dll version doesn't help - I anyway get the original dll if I loaded it once.
Help me! I'm a novice in these things. How could work with dynamic labraries that was so simple in Windows API become so terribly complicated here, in .NET???
What do I do wrong? How can I free the library and load the new, changed one, but with the same name?

That sounds odd. Normally if its a newer version the .net framework will pick up the fact the versions changed and the cached version is updated.

Simple code... maybe, something wrong here...:S

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

namespace PatchedApp
{
    class Program
    {
        public static void LoadInvoke(string path)
        {
            AppDomain sandbox = AppDomain.CreateDomain("Sandbox");
            try
            {
                AssemblyName an = AssemblyName.GetAssemblyName(path);
                Assembly a = sandbox.Load(an);
                Type[] mytypes = a.GetTypes();
                BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
                    BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

                Console.WriteLine(an.Version.ToString());

                foreach (Type t in mytypes)
                {
                    MethodInfo[] mi = t.GetMethods(flags);
                    Object obj = Activator.CreateInstance(t);

                    foreach (MethodInfo m in mi)
                    {
                        m.Invoke(obj, null);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                AppDomain.Unload(sandbox);
            }
        }

        public static void Main(string[] args)
        {
            string file = Directory.GetCurrentDirectory() + "\\PatchedLib.dll";
            string patch = Directory.GetCurrentDirectory() + "\\PatchedLib1.dll";
            string temp = "C:\\_PatchedLib.dll";

            LoadInvoke(file);

            File.Move(file, temp);
            File.Copy(patch, file);
            LoadInvoke(file);

            File.Delete(file);
            File.Move(temp, file);

            Console.ReadKey();
        }
    }
}
This article has been dead for over six months. Start a new discussion instead.