DllImport генерирует System.DllNotFoundException
У меня возникли некоторые трудности при попытке использовать неуправляемый код dll
из моего приложения (написано в C# framework 4.0). Я использую dll
импортировать следующим образом
[DllImport(@"C:\MGW_SDK.dll", EntryPoint = "fInicializaSDK")]
public static extern int fInicializaSDK();
Странно то, что при вызове из моей среды разработки (Windows XP) он работает просто отлично, но на рабочем сервере (Windows7) генерирует следующее исключение:
System.DllNotFoundException
: Невозможно загрузить DLL' C:\MGW_SDK.dll'
: Указанный модуль не может быть найден. (Исключение из HRESULT: 0x8007007E) вComtpaq.AdminPack.SDKWrapper.fInicializaSDK()
вComtpaq.AdminPack.AdminPaqRepository.InitializeSDK()
вC:\Work\AgroIn\AdminPaqRepository.cs
: строка 30
Я уже запустил Dependency Walker, который показывает следующую зависимость как конфликтующую: C:\windows\system32\SHLWAPI.DLL
Я уже пытался скопировать это dll
в мой каталог развертывания
MGW_SDK.dll
находится на c:\
(как говорит путь)
Я уже установил C Runtime Library
Я также заметил некоторые интересные вещи: за исключением, путь развития показывает C:\Work\AgroIn\AdminPaqRepository.cs:line 30
В чем еще может быть проблема здесь?
редактировать
Я создал небольшое консольное приложение с одним из extern
/dllimport
методы, которые я использую из MGW_SDK.dll
и запустил его без проблем (нет DllNotFoundException
как бы то ни было), так что, похоже, это связано с приложением, которое я создаю (служба WCF). Этот сервис размещен на WAS, но я все еще не могу найти проблему.
4 ответа
Ну, это была очень сложная проблема. Он не был связан с зависимостями dll и не был связан с местоположением dll. Это было не о том, как я звонил DllImport
, Это была проблема с разрешениями.
По сути, эта проблема решается удалением и последующим добавлением разрешений на выполнение в папке, где находятся библиотеки DLL. Смотрите эту статью (Wayback machine).
Решение
Клиентское программное обеспечение Oracle 9.2 требует, чтобы вы предоставили привилегию аутентифицированного пользователя для Oracle Home, выполнив следующие действия:
Войдите в Windows как пользователь с правами администратора.
Запустите проводник Windows из меню "Пуск" и перейдите к
ORACLE_HOME
папка. Обычно это папка "Ora92" в папке "Oracle" (т.е.D:\Oracle\Ora92
).Щелкните правой кнопкой мыши папку ORACLE_HOME и выберите параметр "Свойства" в раскрывающемся списке. Должно появиться окно "Свойства".
Нажмите на вкладку "Безопасность" окна "Свойства".
Нажмите на пункт "Аутентифицированные пользователи" в списке "Имя" (в Windows XP список "Имя" называется "Группа или имена пользователей").
Снимите флажок "Чтение и выполнение" в списке "Разрешения" в столбце "Разрешить" (в Windows XP список "Разрешения" называется "Разрешения для прошедших проверку пользователей").
Установите флажок "Читать и выполнить" в столбце "Разрешить" (этот флажок вы только что сняли).
Нажмите кнопку "Дополнительно" и в списке "Записи разрешений" убедитесь, что в списке "Аутентифицированные пользователи" указаны:
Permission = Read & Execute Apply To = This folder, subfolders and files
Если это НЕ так, отредактируйте эту строку и убедитесь, что в раскрывающемся списке "Применить на" установлено значение "Эта папка, подпапки и файлы". Это уже должно быть установлено правильно, но важно, чтобы вы это проверили.
Нажимайте кнопку "ОК", пока не закроете все окна свойств безопасности. Курсор может отображать песочные часы в течение нескольких секунд, поскольку он применяет только что измененные вами разрешения ко всем подпапкам и файлам.
Перезагрузите компьютер, чтобы убедиться, что эти изменения вступили в силу (ВАЖНО).
Перезапустите приложение, и теперь оно должно работать.
Корень C - одно из тех мест, где UAC не позволит вам писать. Иногда непроявленные приложения, которые запрашивают чтение из защищенной области, заканчивают чтение из виртуализированного эквивалента - и вашей DLL там не будет. Попробуйте переместить библиотеку DLL в другую папку (не в корень C, не в папку Program Files) и посмотрите, решит ли это это. Если это так, вы можете оставить его там или (лучше) добавить манифест в ваше приложение для предотвращения виртуализации.
Не знаю, будет ли это работать наверняка, но вы пытались зарегистрировать MGW_SDK.DLL с помощью regsrv32 или другого установочного пакета на Win7 box?
Также попытайтесь выяснить, доступны ли зависимости MGW_SDK.DLL на машине с Win7 (будет ли она работать в системе или в папке вашего приложения)