_Q12_ Ответов: 1

Динамически загружать DLL из определенной папки ?


Я уже загрузил dll из созданной вручную папки внутри program files, обратившись к ней из Обозревателя решений. И это сработало с самого начала !
Но я сделал быстрый тест, переместив свой исполняемый файл в другую папку и запустив его снова. Это дает мне ошибки, но если я помещаю dll с исполняемым файлом, то снова работает нормально. Кроме того, я заглянул в папку Debug, и dll появилась там автоматически после запуска программы из VS. так что... у меня сложилось впечатление, что после того, как я также прочитал об этом феномене в интернете, кажется, что это связано с отладчиком внутри VS или чем-то еще.
я также нахожу этот пост, который дает мне общее представление об этом вопросе...
c# - динамически загружать DLL из определенной папки? - переполнение стека[^]

Интересно, есть ли простое решение или оно так же сложно, как я его уже нахожу?
Я буду реализовывать то, что найду, но ... сначала мне нужно ваше мнение.
Это немного продвинутое то,что я там нахожу, вот почему я колеблюсь.
Спасибо за вашу помощь.(заранее)

Что я уже пробовал:

//at this point i get an error if the dll is missing from folder.
InitializeComponent();

1 Ответов

Рейтинг:
1

Richard MacCutchan

Это не проблема Visual Studio. Во время выполнения загрузка библиотек DLL находится под контролем ОС Windows, управляемой правилами поиска:
- каталог ,в который был загружен файл exes.
- каталог системной библиотеки.
- любые каталоги, перечисленные в пути поиска DLL - см. Функция LoadLibraryA (libloaderapi.h) | Microsoft Docs[^].

Смотреть также Динамически подключаемая библиотека поиск заказа - приложений Windows и Microsoft документы[^].


_Q12_

хорошо, спасибо, но как это написать?
Я нахожу это до сих пор:

открытый частичный класс Form1 : Form, IMessageFilter
{

//загружается, но dll не найдена
[DllImport("kernel32")]
статический extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]строка lpFileName);

// ошибка в LoadLibraryFlags
//[DllImport("kernel32.dll", SetLastError = true)]
//статический модификатор extern указателя IntPtr разделе loadlibraryex(строка lpFileName, указателя IntPtr hReservedNull, LoadLibraryFlags элемент dwflags);

//ошибка на LPCSTR
//[DllImport("kernel32.dll")]
//static extern IntPtr LoadLibraryA(LPCSTR lpLibFileName);


открытый form1()
{

строка dllA = @"c:\Program файлы (x86)\VideoList\AxInterop.WMPLib.dll";
строка dllB = @"c:\Program файлы (x86)\VideoList\Interop.WMPLib.dll";

LoadLibrary(dllA);
LoadLibrary(dllB);

//LoadLibraryEx(dllA, IntPtr.Zero, 0);
//LoadLibraryEx(dllB, IntPtr.Zero, 0);

//LoadLibraryA(dllA);
//LoadLibraryA(dllB);

_Q12_

Этот LPCSTR-это строка из того, что я смог найти до сих пор.
Так что мой более ранний код теперь таков:
[DllImport("kernel32.dll")]
статический extern IntPtr LoadLibraryA(строка lpLibFileName);

Но библиотеки dll все еще не найдены, ошибка в коде в выражении, которое использует эту библиотеку DLL.

_Q12_

я сделал новую папку и поместил туда свою библиотеку dll:
строка dllA = @"c:\VideoList\AxInterop.WMPLib.dll";
строка dllB = @"c:\VideoList\Interop.WMPLib.dll";
я подумал, что, возможно, корень, имеющий пробелы в имени папки, может создать мою ошибку загрузки.
Но никаких изменений, та же ошибка, что он не может их найти.

Richard MacCutchan

Вам нужно использовать LoadLibraryW поскольку строки C* являются UniCode,

_Q12_

я просто ловлю небольшую "ошибку" при загрузке dll. Когда я ссылаюсь на dll из Обозревателя решений, я все еще получаю ошибку (но другую, чем раньше). Поэтому я заглянул в свойства dll и установил для него значение "Embed Interop Type" равным False. И приложение успешно работает. Если я снова удалю ссылочные dll-файлы и изменю свой код с помощью этого свойства?...может быть, это и нужно сделать, но я не знаю, как написать код для этого свойства. Может быть, ты мне поможешь. И большое вам спасибо за вашу помощь до этого момента.

_Q12_

И это ошибка для моего dll кода, который у меня есть сейчас:
Ошибка 1 не удалось найти тип или имя пространства имен "AxWMPLib" (отсутствует ли директива using или ссылка на сборку?)
для:
this.player = новый AxWMPLib.AxWindowsMediaPlayer();
в файле form1.Дизайнер.в CS

Richard MacCutchan

Я просто подумал ... вы не можете ссылаться на элементы этой библиотеки таким образом, так как она не существует во время компиляции. После загрузки его во время выполнения вам нужно будет создать все необходимые объекты с помощью отражения. Честно говоря, я не вижу никакой пользы в том, что вы делаете.

_Q12_

Я понимаю, что ты имеешь в виду. Большое вам спасибо за проявленный интерес. Тогда мне придется переосмыслить функциональность моего приложения.

_Q12_

я использовал LoadLibraryW, как вы сказали, но все та же ошибка, знак dll не читается|не находит. Если это поможет, то эти dll-файлы предназначены для управления WindowsMediaPlayer из VS2010.

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadLibraryW(string lpLibFileName);
открытый form1()
{
строка dllA = @"c:\VideoList\AxInterop.WMPLib.dll";
строка dllB = @"c:\VideoList\Interop.WMPLib.dll";
LoadLibraryW(dllA);
LoadLibraryW(dllB);

Richard MacCutchan

Я думаю, что вы не сможете решить эту проблему, не пройдя через код с помощью отладчика, чтобы точно увидеть, что происходит. Это может быть, что вам нужно Маршалл строки с помощью функции LoadLibrary звонки.