Inno Setupで依存関係のあるDLLをロードすると、アンインストーラーで「DLLをインポートできません」で失敗しますが、インストーラーでは機能します

Nov 26 2020

プログラムをアンインストールすると、次のエラーが発生します。

dllをインポートできません:<utf8> c:\ TestProg \ IsStart.dll

私はここで何を間違えましたか?誰かが私がこの問題を解決するのを手伝ってくれる?

CheckO4TaskMngrSvcStopAndUninstallO4TaskManager Service:を停止して削除します

コードは次のとおりです。

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

回答

1 MartinPrikryl Nov 30 2020 at 16:54

私は一連の異なる問題があったと信じています(そのうちのいくつかは確かに私の間違った提案に基づいていました)。

正しいコードは、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';

キーポイント:

  • 元々の問題は、アンインストーラーのインポート宣言にloadwithalteredsearchpathフラグがないことでした。依存関係をロードするために必要です(sqlite3.dll)。
  • アンインストーラーで使用するには、に依存関係(sqlite3.dll)をインストールする必要があり{app}ます。
  • インストールされている依存関係のコピーは、プライマリDLLが検索する名前と一致する必要があります(sqlite3.dllではなくsqlite3x86.dll)。
  • external宣言内のDLLの名前は、元のファイル名ではなく、宛先ファイル名(DestName: IsStart.dllDestName: sqlite3.dll)と一致する必要があります。
  • 依存関係は、インストーラー内から(files:プレフィックス付きで)DLLをロードする場合にのみ、宣言にリストする必要があり、リストすることができます。物理パス({app}\IsStart.dll)からDLLをロードする場合ではありません。依存関係を一覧表示する唯一の目的は、インストーラーが依存関係を抽出することです(ロードせず、プライマリDLLがロードするため、前のポイント)。すべてのファイルがすでにインストールされている(インストールされている必要がある)ため、物理ファイルをロードするときにリストする必要はありません。を使用する{app}\primary.dll,{app}\dependency.dllと、アンインストーラーは実際に名前の付いたファイルを読み込もうとしますが、{app}\primary.dll,{app}\dependency.dll明らかに失敗します。
  • {tmp}も何もインストールしても意味がありません{src}
АндрейА Nov 29 2020 at 06:06

IsStart.dllはsqlite3.dllに依存していますか?sqlite3x86.dllが何であるかわからない可能性があります。いくつかのプラグインを使用したtotalcmdでは、見逃したdllを表示できます