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, выполнив следующие действия:

  1. Войдите в Windows как пользователь с правами администратора.

  2. Запустите проводник Windows из меню "Пуск" и перейдите к ORACLE_HOME папка. Обычно это папка "Ora92" в папке "Oracle" (т.е. D:\Oracle\Ora92).

  3. Щелкните правой кнопкой мыши папку ORACLE_HOME и выберите параметр "Свойства" в раскрывающемся списке. Должно появиться окно "Свойства".

  4. Нажмите на вкладку "Безопасность" окна "Свойства".

  5. Нажмите на пункт "Аутентифицированные пользователи" в списке "Имя" (в Windows XP список "Имя" называется "Группа или имена пользователей").

  6. Снимите флажок "Чтение и выполнение" в списке "Разрешения" в столбце "Разрешить" (в Windows XP список "Разрешения" называется "Разрешения для прошедших проверку пользователей").

  7. Установите флажок "Читать и выполнить" в столбце "Разрешить" (этот флажок вы только что сняли).

  8. Нажмите кнопку "Дополнительно" и в списке "Записи разрешений" убедитесь, что в списке "Аутентифицированные пользователи" указаны:

      Permission = Read & Execute 
      Apply To = This folder, subfolders and files 
    

    Если это НЕ так, отредактируйте эту строку и убедитесь, что в раскрывающемся списке "Применить на" установлено значение "Эта папка, подпапки и файлы". Это уже должно быть установлено правильно, но важно, чтобы вы это проверили.

  9. Нажимайте кнопку "ОК", пока не закроете все окна свойств безопасности. Курсор может отображать песочные часы в течение нескольких секунд, поскольку он применяет только что измененные вами разрешения ко всем подпапкам и файлам.

  10. Перезагрузите компьютер, чтобы убедиться, что эти изменения вступили в силу (ВАЖНО).

Перезапустите приложение, и теперь оно должно работать.

Корень C - одно из тех мест, где UAC не позволит вам писать. Иногда непроявленные приложения, которые запрашивают чтение из защищенной области, заканчивают чтение из виртуализированного эквивалента - и вашей DLL там не будет. Попробуйте переместить библиотеку DLL в другую папку (не в корень C, не в папку Program Files) и посмотрите, решит ли это это. Если это так, вы можете оставить его там или (лучше) добавить манифест в ваше приложение для предотвращения виртуализации.

Вы пытались использовать сборку журнала привязки сборки?

Просмотр журнала привязки сборки

Не знаю, будет ли это работать наверняка, но вы пытались зарегистрировать MGW_SDK.DLL с помощью regsrv32 или другого установочного пакета на Win7 box?

Также попытайтесь выяснить, доступны ли зависимости MGW_SDK.DLL на машине с Win7 (будет ли она работать в системе или в папке вашего приложения)

Другие вопросы по тегам