Ładowanie biblioteki DLL z zależnościami w Inno Setup kończy się niepowodzeniem w dezinstalatorze z komunikatem „Nie można importować DLL”, ale działa w instalatorze

Nov 26 2020

Podczas odinstalowywania programu pojawia się następujący błąd:

Nie można zaimportować dll: <utf8> c: \ TestProg \ IsStart.dll

Co tu zrobiłem źle? Czy ktoś może mi pomóc rozwiązać ten problem?

CheckO4TaskMngrSvcStopAndUninstallzatrzymuje i usuwa O4TaskManager Service:

Oto kod:

[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;

Odpowiedzi

1 MartinPrikryl Nov 30 2020 at 16:54

Uważam, że istniało wiele różnych problemów (z których niektóre były rzeczywiście oparte na moich błędnych sugestiach).

Prawidłowy kod to 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';

Kluczowe punkty:

  • Pierwotnym problemem był brak loadwithalteredsearchpathflagi w deklaracji importu dla dezinstalatora. Potrzebujesz go do załadowania zależności ( sqlite3.dll).
  • Musisz zainstalować zależności ( sqlite3.dll) na {app}potrzeby dezinstalatora.
  • Zainstalowana kopia zależności musi być zgodna z nazwą, której szuka podstawowa biblioteka DLL (a sqlite3.dllnie sqlite3x86.dll).
  • Nazwa bibliotek DLL w externaldeklaracji musi odpowiadać docelowej nazwie pliku ( DestName: IsStart.dll, DestName: sqlite3.dll), a nie oryginalnej.
  • Zależność musi i może być wymieniona w deklaracji tylko podczas ładowania bibliotek DLL z poziomu instalatora (z files:prefiksem). Nie podczas ładowania biblioteki DLL ze ścieżki fizycznej ( {app}\IsStart.dll). Jedynym celem wyszczególnienia zależności jest wyodrębnienie jej przez instalator (nie ładuje jej, a robi to podstawowa biblioteka DLL, stąd poprzedni punkt). Nie ma potrzeby umieszczania jej na liście podczas ładowania plików fizycznych, ponieważ wszystkie pliki są (muszą) już być zainstalowane. Jeśli używasz {app}\primary.dll,{app}\dependency.dll, deinstalator faktycznie spróbuje załadować plik o nazwie {app}\primary.dll,{app}\dependency.dll- oczywiście bez powodzenia.
  • Nie ma sensu instalować niczego na {tmp}nor {src}.
АндрейА Nov 29 2020 at 06:06

IsStart.dll zależy od sqlite3.dll? Może nie wiem, co to jest sqlite3x86.dll. W totalcmd z jakąś wtyczką możesz wyświetlić pominięty plik dll