Могу ли я загрузить несколько DLL-файлов, используя LoadLibrary в NSIS? - PullRequest
0 голосов
/ 22 октября 2018

Я загрузил несколько dll, используя LoadLibrary в сценарии NSIS, как часть моего проекта.Потому что другие библиотеки являются ссылками основной библиотеки.После этого, как вызвать функцию, используя GetProcAddress?Поскольку я загрузил несколько библиотек DLL.

Ниже приведен фрагмент кода:

    !include LogicLib.nsh

    Section
    SetOutPath $InstDir
    File drvutil.dll
    System::Call 'KERNEL32::LoadLibrary(t "$InstDir\drvutil.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\UPSControls.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\UPSDevice.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\pdcdll.dll")p.r8 ?e'
    Pop $7
    ${If} $8 P<> 0
        MessageBox MB_OK 'Successfully loaded "$InstDir\drvutil.dll" @ $8'
        System::Call 'KERNEL32::GetProcAddress(pr8, m "IsUPSPresent")p.r9 ?e'
        Pop $7
        ${If} $9 P<> 0
            MessageBox MB_OK 'Successfully found "IsUPSPresent" @ $9'
        ${Else}
            MessageBox MB_ICONSTOP 'Unable to find "IsUPSPresent", error $7'
        ${EndIf}
        System::Call 'KERNEL32::FreeLibrary(pr8)'
    ${Else}
        MessageBox MB_ICONSTOP 'Unable to load "$InstDir\drvutil.dll", error $7'
    ${EndIf}

Когда я запускаю этот скрипт, он успешно загружает библиотеку DLL.Но это не загрузка функции.Не могли бы вы помочь мне решить проблему?

1 Ответ

0 голосов
/ 22 октября 2018

Когда я запускаю этот скрипт, он успешно загружает DLL.

Вы проверяете неправильный HMODULE в своем опубликованном примере!Вы просто проверяете, правильно ли загружен файл pdcdll.dll, а не .DLL, который вы хотите проверить.

В идеале вы должны иметь достаточный опыт работы с Win32 при использовании системного плагина.

LoadLibrary загрузит зависимые .DLLs для вас, вам не нужно делать это вручную в большинстве случаев.Одна потенциальная проблема заключается в том, что NSIS активирует некоторые дополнительные средства защиты , чтобы избежать загрузки угонщиков-.DLL, и это может помешать загрузке .DLL его зависимостей.

Я приведу вам полный пример здеськоторый загружает каждый файл .DLL вручную, но вы не должны делать это нормально, просто загрузите нужный файл .DLL и позвольте Windows разрешить все остальное за вас.

!include LogicLib.nsh

Section
SetOutPath $InstDir
File drvutil.dll
File UPSControls.dll
File UPSDevice.dll
File pdcdll.dll

System::Call 'KERNEL32::AddDllDirectory(w "$InstDir")' ; Tell Windows we trust all .DLLs in this directory

System::Call 'KERNEL32::LoadLibrary(t "$InstDir\pdcdll.dll")p.r8'
${IfThen} $8 P= 0 ${|} MessageBox MB_ICONSTOP "DEBUG: Failed to load pdcdll.dll" ${|}
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\UPSDevice.dll")p.r8'
${IfThen} $8 P= 0 ${|} MessageBox MB_ICONSTOP "DEBUG: Failed to load UPSDevice.dll" ${|}
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\UPSControls.dll")p.r8'
${IfThen} $8 P= 0 ${|} MessageBox MB_ICONSTOP "DEBUG: Failed to load UPSControls.dll" ${|}

System::Call 'KERNEL32::LoadLibrary(t "$InstDir\drvutil.dll")p.r8 ?e'
Pop $7 ; Get ?e result
${IfThen} $8 P= 0 ${|} MessageBox MB_ICONSTOP "Failed to load drvutil.dll, error $7" ${|}
${If} $8 P<> 0
  System::Call 'KERNEL32::GetProcAddress(pr8, m "IsUPSPresent")p.r9 ?e'
  Pop $7 ; Get ?e result
  ${IfThen} $9 P= 0 ${|} MessageBox MB_ICONSTOP "Failed to find the exported function, error $7. Inspect the .DLL with Dependency Walker to make sure the function is exported with the correct un-decorated name!" ${|}
${EndIf}

SectionEnd

Если вы получили сообщение «Не удалось загрузить drvutil.dll»"сообщение, то вам нужно посмотреть на зависимости .DLLs и т. д.

Если вы получили сообщение" Не удалось найти экспортированную функцию ", значит, вы не правильно экспортировали функцию .Имя функции не должно быть оформлено . Dependency Walker покажет вам имя экспортируемой функции.Если вы не можете удалить оформление, вы можете передать оформленное имя непосредственно в GetProcAddress, но при этом вам следует иметь в виду, что имя, вероятно, не совпадает, если вы компилируете как 64-битный или если вы переключаетесь на другой компиляторvendor.

Это должно выглядеть так:

Dependency Walker

...