Carregar DLL com dependências no Inno Setup falha no desinstalador com “Não é possível importar DLL”, mas funciona no instalador

Nov 26 2020

Quando eu desinstalo o programa, recebo este erro:

Não é possível importar dll: <utf8> c: \ TestProg \ IsStart.dll

O que eu fiz de errado aqui? Alguém pode me ajudar a resolver esse problema?

CheckO4TaskMngrSvcStopAndUninstallpara e exclui O4TaskManager Service:

Aqui está o código:

[Files]
Source: "IsStartServer.dll"; DestDir: "{tmp}"; DestName: IsStart.dll
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{src}"; DestName: sqlite3.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
Source: "sqlite3x64.dll"; DestDir: "{app}"

[Code]
function TaskMngrInst: LongBool;                                                
external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';

function TaskMngrUninst: LongBool;                                                
external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall uninstallonly';

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
    begin
      TaskMngrInst();
    end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usUninstall then
    begin
      TaskMngrUninst();
      DeleteFile(ExpandConstant('{app}\sqlite3.dll'));
      DeleteFile(ExpandConstant('{app}\IsStart.dll'));
      RenameFile('{app}\sqlite3x64.dll)', '{app}\sqlite3.dll');
    end;
end;

Respostas

1 MartinPrikryl Nov 30 2020 at 16:54

Acredito que houve uma série de problemas diferentes (alguns dos quais realmente foram baseados em minhas sugestões erradas).

O código correto é, imo:

[Files]
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
[Code]
function TaskMngrInst: LongBool;                                                
  external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';

function TaskMngrUninst: LongBool;                                                
  external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall loadwithalteredsearchpath uninstallonly';

Os pontos principais:

  • Seu problema original era a falta de um loadwithalteredsearchpathsinalizador na declaração de importação para o desinstalador. Você precisa disso para carregar as dependências ( sqlite3.dll).
  • Você precisa instalar as dependências ( sqlite3.dll) para {app}uso pelo desinstalador.
  • A cópia instalada da dependência deve corresponder ao nome que a DLL primária procura ( sqlite3.dll, não sqlite3x86.dll).
  • O nome das DLLs na externaldeclaração deve corresponder ao nome do arquivo de destino ( DestName: IsStart.dll, DestName: sqlite3.dll), não ao original.
  • A dependência deve e pode ser listada na declaração apenas ao carregar as DLLs de dentro do instalador (com o files:prefixo). Não ao carregar a DLL de um caminho físico ( {app}\IsStart.dll). O único propósito de listar a dependência é que o instalador a extraia (não a carrega, a DLL principal sim, daí o ponto anterior). Você não precisa listá-lo ao carregar arquivos físicos, pois todos os arquivos já estão (devem estar) instalados. Se você usar {app}\primary.dll,{app}\dependency.dll, o desinstalador tentará realmente carregar um arquivo com um nome {app}\primary.dll,{app}\dependency.dll- obviamente falhando.
  • Não adianta instalar nada para {tmp}nem {src}.
АндрейА Nov 29 2020 at 06:06

IsStart.dll depende de sqlite3.dll? Pode ser que não saiba o que é sqlite3x86.dll. No totalcmd com algum plugin, você pode ver dll perdida