Inno setup 调用连续DLL';从Inno设置中的{tmp}删除

Inno setup 调用连续DLL';从Inno设置中的{tmp}删除,inno-setup,Inno Setup,我想在我的Inno安装脚本中使用我在Delphi中创建的DLL(比如“a.DLL”),该脚本使用一组其他DLL('B.DLL'、'C.DLL'、…)。所有这些dll文件都包含在文件部分中,如下所示: [Files] Source:"libs\*.dll"; Flags: dontcopy 在代码部分,我按照联机帮助中的描述声明了所用DLL的方法,并添加了loadwithalteredsearchpath标志: procedure MyMethod; external 'MyMethod@fil

我想在我的Inno安装脚本中使用我在Delphi中创建的DLL(比如“a.DLL”),该脚本使用一组其他DLL('B.DLL'、'C.DLL'、…)。所有这些dll文件都包含在文件部分中,如下所示:

[Files]
Source:"libs\*.dll"; Flags: dontcopy
在代码部分,我按照联机帮助中的描述声明了所用DLL的方法,并添加了loadwithalteredsearchpath标志:

procedure MyMethod; external 'MyMethod@files:A.dll,B.dll,C.dll stdcall loadwithalteredsearchpath';
当安装程序启动时,所有需要的文件都被复制到常量{#tmp}所指向的临时目录中。然而,MyMethod开始执行时很好(用一些Showmessages检查),但是当该方法尝试使用其他DLL时,整个过程就中断了

在{#tmp}的临时文件夹旁边,在安装过程中创建了另外两个临时目录(都使用'IS-xxxxx.tmp'模式),其中包含'setup.tmp'(在{#tmp}中不存在)。现在,当我在安装开始时手动将所有DLL(除A.DLL外)复制到这两个其他目录中时,一切正常。但是,当我让它只按照脚本中的定义运行时,A.dll似乎找不到其他库

有人知道为什么会发生这种情况吗?我该如何解决?这似乎是路径的问题,但我认为Inno安装程序将tmp dir添加到路径中,以便安装程序可以找到DLL(它确实找到了,但奇怪的是,仅针对a.DLL)

提前感谢您的帮助!:)

编辑:在Inno安装过程中,通过调用“外来”DLL(B.DLL,C.DLL,…)中的一个方法来使用其中一个DLL(B.DLL,C.DLL,…)时,我得到的实际错误:

Access violation at address 00408CC7 in module 'setup.tmp'. Read of adress 00000000.
编辑2:我想我意识到了问题发生的原因:在我自己的A.dll中,我发现setup.exe不是在{tmp}内执行的,而是在安装开始时创建的另外两个临时目录之一。看起来,库搜索路径(第二个链接)中添加的不是{tmp},而是当前的工作目录(因此,执行inno的目录)。这将解释为什么只有在手动复制到另一个临时目录时才能访问其他库(B.dll、C.dll…)。我假设从{tmp}提取并调用.dll没有问题,因为它在外部命令中被称为“主库”。我认为使用loadwithalteredsearchpath其他库可以保留在同一个目录中,但这似乎不起作用

但我现在如何才能巧妙地解决这个问题呢?我想我可以将DLL手动复制到安装路径(通过使用ExtractFilePath(ParamStr(0)),在它们被提取到{tmp}之后解决这个问题。但是这似乎是一个肮脏的解决方法,因为在Inno安装程序中使用DLL应该是不同的


  • 我不确定您是否只加载DLL而不在系统注册表中注册它们。但是,您的第一次编辑显示了由尝试访问注册表的某些堆栈触发的错误,因此我假设您是。在这种情况下,我只需使用批处理文件(在CMD控制台中触发命令)来注册我的DLL,就像我将逐个注册一样:

     @echo off
     echo Registering DevExpress DLLs
     %~dp0gacutil.exe /i %~dp0DevExpress.BonusSkins.v12.1.dll
     %~dp0gacutil.exe /i %~dp0DevExpress.Charts.v12.1.Core.dll
    
    因此,我将其放在iss脚本的运行部分:

    [Run]
    Filename:C:\myFolder\RegisterDevExpress.bat"
    

    希望这能有所帮助。

    你确定这三个DLL没有其他依赖关系,或者其他错误吗?因为加载错误通常会导致无法调用DLL中的任何内容,而不是部分执行。嗯,我不完全确定。但是我事先在一个简单的Delphi程序中测试了设置,当e所有库(A.dll,B.dll,C.ll,…)都在程序exe的目录中,一切正常。这对我来说似乎不是一个加载错误,因为其他库(B.dll,C.dll,…)也集成得很好,但当我想使用其中一个库(调用它们的方法之一)时,它就会中断。->添加了我得到的实际错误。“读取地址0”听起来像是空指针访问。请确保在编译库时使用“正常”链接,而不是延迟加载链接。当然,在实际运行的DLL代码中没有任何空指针。我在导出方法时创建了一个没有任何特定设置的.DLL,所以我想我使用的是“正常”链接“链接。我已经发现,我的DLL中实际上有一个空指针,但我认为这不是由我自己的程序引起的,也不是可以修复的。问题是,我使用的是一个组件(来自DCEF3的TChromium),其方法主要使用其他库(B.DLL,C.DLL…),而我对两者都没有任何影响。当我在Inno Setup中调用此组件的构造函数时,不会出现任何错误,但相应的变量没有指针,因此任何下一次访问都将失败(请参阅main post中的错误).但我不认为这是我的A.dll的错误,因为1.我在一个单独的delphi程序中在Inno安装程序外测试了它,它工作得很好;2.Inno安装程序中出现错误只取决于我是否手动复制上述tmp文件夹中的dll文件,而不取决于任何程序更改。所以我猜,每当我使用其他DLL通过调用组件方法(如构造函数)无法找到,尽管它们位于同一目录中。(Sry,有两条注释,但我无法在字符边界内表达自己:-()只要它们不是例如.NET库(您使用gacutil的地方),就不会注册DLL库),或者他们没有导出
    DllRegisterServer
    函数(这是您使用Regsvr32的地方)。再说一次,如果您有整个
    [运行],为什么要使用批处理脚本
    部分,以及背后强大的Pascal脚本代码引擎。不,它必须是嵌入在安装程序中的古老批处理脚本…
    :)@TLama,这些是Dot.Net库(我假设)。您可以扩展注册每个DLL文件吗