Как подгрузить .dll файлы к .exe? [дубликат]

146
02 августа 2019, 03:30

На данный вопрос уже ответили:

  • Задать путь для DLL файла копируемого локально 2 ответа
  • Структуризация проэкта Visual Studio. Как настроить чтобы все зависимые dll ки скидывались в папку? 1 ответ

Как подгрузить .dll файлы из другой папки?

Файл .exe рядом с .dll работает корректно. Но если переместить .exe файл в любое другое место, то .exe не находит эти .dll.

Вопрос: Как задать папку откуда будут браться эти .dll ?

Без конфига (файла проекта)!

Answer 1

Если без конфига, то только так:

using System.Reflection;
//...
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
     string newdir = "c:\\MyDirectory";        
     string path = Path.Combine(newdir, args.Name);
     if (!path.EndsWith(".dll"))
     {
         path = path + ".dll";
     }
     Assembly ass = Assembly.LoadFile(path);
     return ass;      
}
//...
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Answer 2

Дополню вопрос касательно нативных DLL на основании этого ответа:

Нужно через P/Invoke описать 2 функции:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);
//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
     int errorCode = Marshal.GetLastWin32Error();
     throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}
//Free
if(Handle != IntPtr.Zero)
        FreeLibrary(Handle);

Если мы хотим работать с функцией из загруженной либы(а мы это хотим, иначе не грузили бы), то нужно еще определить GetProcAddress

[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); 

    IntPtr funcaddr = GetProcAddress(Handle,functionName);

И потом создать делегат

YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);

Помните, что C# не поддерживает работу с неуправляемыми объектами=> возможны только API вызовы. Если нужно создавать неуправляемые объекты, то нужно делать прослойку на C++/CLI

Answer 3

Вы можете подгружать DLL через рефлексию непосредственно в рантайме:

namespace ConsoleApplication1
{
using System;
using System.Reflection;
class Program
{
    static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
        foreach(Type type in DLL.GetExportedTypes())
        {
            var c = Activator.CreateInstance(type);
            type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {@"Hello"});
        }
        Console.ReadLine();
    }
}
}

Источник: тут.

READ ALSO
c# - Как сохранять фильтр при пагинации? ASP.NET MVC

c# - Как сохранять фильтр при пагинации? ASP.NET MVC

Необходимо при переходе на другую страницу, запомнить то, что произошло на первойТо есть фильтрацию таблицы

145
Сборщик мусора c# не очищает память

Сборщик мусора c# не очищает память

Есть статичный метод

145
Laravel Выбор таблицы при авторизации

Laravel Выбор таблицы при авторизации

При авторизации нужно обратится именно в ту таблицу которая была выбрана при входе

122