我可以使用NSIS中的LoadLibrary加载多个DLL吗?

我可以使用NSIS中的LoadLibrary加载多个DLL吗?,nsis,Nsis,作为项目的一部分,我在NSIS脚本中使用LoadLibrary加载了多个DLL。因为其他dll是主dll的引用。 之后,如何使用GetProcAddress调用函数?因为我已经加载了多个DLL 下面是我的代码片段: !include LogicLib.nsh Section SetOutPath $InstDir File testutil.dll System::Call 'KERNEL32::LoadLibrary(t "$Inst

作为项目的一部分,我在NSIS脚本中使用LoadLibrary加载了多个DLL。因为其他dll是主dll的引用。 之后,如何使用GetProcAddress调用函数?因为我已经加载了多个DLL

下面是我的代码片段:

    !include LogicLib.nsh
    
    Section
    SetOutPath $InstDir
    File testutil.dll
    System::Call 'KERNEL32::LoadLibrary(t "$InstDir\Testutil.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\TestControls.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\TestDevice.dll")p.r8 ?e'
System::Call 'KERNEL32::LoadLibrary(t "$InstDir\loadtestdll.dll")p.r8 ?e'
    Pop $7
    ${If} $8 P<> 0
        MessageBox MB_OK 'Successfully loaded "$InstDir\testutil.dll" @ $8'
        System::Call 'KERNEL32::GetProcAddress(pr8, m "IsTherePower")p.r9 ?e'
        Pop $7
        ${If} $9 P<> 0
            MessageBox MB_OK 'Successfully found "IsTherePower" @ $9'
        ${Else}
            MessageBox MB_ICONSTOP 'Unable to find "IsTherePower", error $7'
        ${EndIf}
        System::Call 'KERNEL32::FreeLibrary(pr8)'
    ${Else}
        MessageBox MB_ICONSTOP 'Unable to load "$InstDir\testutil.dll", error $7'
    ${EndIf}
!包括LogicLib.nsh
部分
SetOutPath$InstDir
文件testutil.dll
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\Testutil.dll”)p.r8?e'
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\TestControls.dll”)p.r8?e'
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\TestDevice.dll”)p.r8?e'
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\loadtestdll.dll”)p.r8?e'
流行音乐7美元
${If}$8 P 0
MessageBox MB_OK'已成功加载“$InstDir\testutil.dll”@$8'
系统::调用“内核32::GetProcAddress(pr8,m“IsTherePower”)p.r9?e”
流行音乐7美元
${If}$9 P 0
MessageBox MB_OK'已成功找到“IsTherePower”@$9'
${Else}
MessageBox MB_ICONSTOP'无法找到“IsTherePower”,错误$7'
${EndIf}
系统::调用“内核32::免费库(pr8)”
${Else}
MessageBox MB_ICONSTOP'无法加载“$InstDir\testutil.dll”,错误$7'
${EndIf}
当我运行此脚本时,它正在成功加载DLL。但它并没有加载函数。你能帮我解决这个问题吗

当我运行此脚本时,它正在成功加载DLL

您在发布的示例中检查了错误的HMODULE!您只是检查是否正确加载了pdcdll.dll,而不是要检查的.dll

理想情况下,在使用系统插件时,您应该对Win32有一定的经验

LoadLibrary
将依赖于加载。DLL对于您来说,在大多数情况下不必手动执行。一个潜在的问题是,为了避免加载劫持-.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
!包括LogicLib.nsh
部分
SetOutPath$InstDir
文件drvutil.dll
文件UPSControls.dll
文件UPSDevice.dll
文件pdcdll.dll
系统::调用“KERNEL32::AddDllDirectory(w“$InstDir”);告诉Windows我们信任此目录中的所有.dll
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\pdcdll.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:未能加载pdcdll.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\UPSDevice.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:无法加载UPSDevice.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\upsconts.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:无法加载UPSControls.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\drvutil.dll”)p.r8?e'
流行音乐7美元;结果如何
${IfThen}$8 P=0${{}MessageBox MB|u ICONSTOP“未能加载drvutil.dll,错误$7”${{124;}
${If}$8 P 0
系统::调用'KERNEL32::GetProcAddress(pr8,m“isuppresent”)p.r9?e'
流行音乐7美元;结果如何
${IfThen}$9 P=0${{124;}MessageBox MB|u ICONSTOP“未能找到导出的函数,错误$7。请使用依赖项遍历器检查.DLL,以确保该函数以正确的未修饰名称导出!”${124;
${EndIf}
分段结束
如果收到“加载drvutil.dll失败”消息,则需要查看.dll依赖项等

如果您收到“未能找到导出的函数”消息,则您尚未找到。函数名不应为空。将显示导出的函数名。如果无法删除修饰,则可以将修饰后的名称直接传递给
GetProcAddress
,但需要记住,如果编译为64位或更改为其他编译器供应商,则名称可能不同

应该是这样的:

当我运行此脚本时,它正在成功加载DLL

您在发布的示例中检查了错误的HMODULE!您只是检查是否正确加载了pdcdll.dll,而不是要检查的.dll

理想情况下,在使用系统插件时,您应该对Win32有一定的经验

LoadLibrary
将依赖于加载。DLL对于您来说,在大多数情况下不必手动执行。一个潜在的问题是,为了避免加载劫持-.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
!包括LogicLib.nsh
部分
SetOutPath$InstDir
文件drvutil.dll
文件UPSControls.dll
文件UPSDevice.dll
文件pdcdll.dll
系统::调用“KERNEL32::AddDllDirectory(w“$InstDir”);告诉Windows我们信任此目录中的所有.dll
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\pdcdll.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:未能加载pdcdll.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\UPSDevice.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:无法加载UPSDevice.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\upsconts.dll”)p.r8'
${IfThen}$8 P=0${{124;}MessageBox MB|u ICONSTOP“调试:无法加载UPSControls.dll”${124;}
系统::调用'KERNEL32::LoadLibrary(t“$InstDir\drvutil.dll”)p.r8?e'
流行音乐7美元;结果如何
${IfThen}$8 P=0${{}MessageBox MB|u ICONSTOP“未能加载drvutil.dll,错误$7”${{124;}
${If}$8 P 0
系统::调用'KERNEL32::GetProcAddress(pr8,m“isuppresent”)p.r9?e'
流行音乐7美元;结果如何
${IfThen}$9 P=0${{124;}MessageBox MB|u ICONSTOP“未能找到导出的函数,错误$7。请使用依赖项遍历器检查.DLL,以确保该函数以正确的未修饰名称导出!”${124;
${EndIf}
分段结束
如果你得到