Ł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?
CheckO4TaskMngrSvcStopAndUninstall
zatrzymuje 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.dll
niesqlite3x86.dll
). - Nazwa bibliotek DLL w
external
deklaracji 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