2012-05-21 13 views
9

InnoSetupに、ユーザーによって変更されたファイル(InnoSetupによってインストールされたものとは異なる===)をアンインストールしないようにする方法InnoSetup:変更されたファイルをアンインストールしない

新しいバージョンを既存のものにインストールする場合、InnoSetupは変更されたファイルを上書きするかどうかをユーザーに確認する必要がありますが、純粋なアンインストールでは確認せずにアンインストールする必要があります。

+0

たぶん、あなたは 'UninsNeverUninstall'を使用することができますフラグをつけて、 'CurUninstallStepChanged'' usPostUninstall'に '[CODE]'セクションを追加します。すべてのTXTファイルがCRCチェックされ、CRCが等しくなった場合、またはCRCが等しくなければ変更されたファイルについて通知されます。削除されました。 – RobeN

+1

ファイルは何ですか?設定ファイルの場合は、別の名前のデフォルトファイルをインストールして、それが存在しない場合はメイン設定ファイルの場所にコピーする方がよいでしょう。それらがユーザーファイルの場合、セットアップはそれらにまったく触れないでください。 – Deanna

答えて

6

私は最近同様の問題がありました。これは、テキストファイル(プロファイル)が最後にインストールされたときにインストールされたものから変更されたかどうかを検出する私の解決策でした。

ISPP(Inno Setup Pre-Processor)を使用して、私は、以前のインストールと、現在のファイルのハッシュを比較する「チェック」イベントハンドラで

[Code] 
var 
    PreviousDataCache : tStringList; 

function InitializeSetup() : boolean; 
begin 
    // Initialize global variable 
    PreviousDataCache := tStringList.Create(); 
    result := TRUE; 
end; 

function BoolToStr(Value : boolean) : string; 
begin 
    if (not Value) then 
     result := 'false' 
    else 
     result := 'true'; 
end; 

:私はいくつかの有用なものを定義する「コード」セクションの上部に

[Files] 
; ... 
#define FindHandle 
#define FindResult 
#define Mask "Profiles\*.ini" 
#sub ProcessFoundFile 
    #define FileName "Profiles\" + FindGetFileName(FindHandle) 
    #define FileMd5 GetMd5OfFile(FileName) 
    Source: {#FileName}; DestDir: {app}\Profiles; Components: profiles; \ 
     Check: ProfileCheck('{#FileMd5}'); AfterInstall: ProfileAfterInstall('{#FileMd5}'); 
#endsub 
#for {FindHandle = FindResult = FindFirst(Mask, 0); FindResult; FindResult = FindNext(FindHandle)} ProcessFoundFile 

:時間をコンパイルします。

function ProfileCheck(FileMd5 : string) : boolean; 
var 
    TargetFileName, TargetFileMd5, PreviousFileMd5 : string; 
    r : integer; 
begin 
    result := FALSE; 
    TargetFileName := ExpandConstant(CurrentFileName()); 
    Log('Running check procedure for file: ' + TargetFileName); 

    if not FileExists(TargetFileName) then 
    begin 
     Log('Check result: Target file does not exist yet.'); 
     result := TRUE; 
     exit; 
    end; 

    try 
     TargetFileMd5 := GetMd5OfFile(TargetFileName); 
    except 
     TargetFileMd5 := '(error)'; 
    end; 
    if (CompareText(TargetFileMd5, FileMd5) = 0) then 
    begin 
     Log('Check result: Target matches file from setup.'); 
     result := TRUE; 
     exit; 
    end; 

    PreviousFileMd5 := GetPreviousData(ExtractFileName(TargetFileName), ''); 
    if (PreviousFileMd5 = '') then 
    begin 
     r := MsgBox(TargetFileName + #10#10 + 
     'The existing file is different from the one Setup is trying to install. ' + 
     'It is recommended that you keep the existing file.' + #10#10 + 
     'Do you want to keep the existing file?', mbConfirmation, MB_YESNO); 
     result := (r = idNo); 
     Log('Check result: ' + BoolToStr(result)); 
    end 
    else if (CompareText(PreviousFileMd5, TargetFileMd5) <> 0) then 
    begin 
     r := MsgBox(TargetFileName + #10#10 + 
     'The existing file has been modified since the last run of Setup. ' + 
     'It is recommended that you keep the existing file.' + #10#10 + 
     'Do you want to keep the existing file?', mbConfirmation, MB_YESNO); 
     result := (r = idNo); 
     Log('Check result: ' + BoolToStr(result)); 
    end 
    else 
    begin 
     Log('Check result: Existing target has no local modifications.'); 
     result := TRUE; 
    end; 
end; 

"AfterInstall"イベントハンドラでは、ファイルハッシュを レジストリに保存するようマークします。ファイルの移動が失敗した場合でも、私のテストでは、イベントがトリガされたため、(ターゲット・ファイルは読み取り専用です)私は、ファイルの移動が成功したかどうかを調べるために、再度ハッシュを比較します

procedure ProfileAfterInstall(FileMd5 : string); 
var 
    TargetFileName, TargetFileMd5 : string; 
begin 
    TargetFileName := ExpandConstant(CurrentFileName()); 
    try 
     TargetFileMd5 := GetMd5OfFile(TargetFileName); 
    except 
     TargetFileMd5 := '(error)'; 
    end; 
    if (CompareText(TargetFileMd5, FileMd5) = 0) then 
    begin 
     Log('Storing hash of installed file: ' + TargetFileName); 
     PreviousDataCache.Add(ExtractFileName(TargetFileName) + '=' + FileMd5); 
    end; 
end; 

procedure RegisterPreviousData(PreviousDataKey : integer); 
var 
    Name, Value : string; 
    i, n : integer; 
begin 
    for i := 0 to PreviousDataCache.Count-1 do 
    begin 
     Value := PreviousDataCache.Strings[i]; 
     n := Pos('=', Value); 
     if (n > 0) then 
     begin 
     Name := Copy(Value, 1, n-1); 
     Value := Copy(Value, n+1, MaxInt); 
     SetPreviousData(PreviousDataKey, Name, Value); 
     end; 
    end; 
end; 
+0

RegisterPreviousData()を呼び出すときに尋ねることはできますか? –

+2

@JulienM: 'RegisterPreviousData'は、その名前を持つ関数が存在する場合、Inno Setupによって自動的に呼び出されるイベント関数です。詳細については、Inno Setupヘルプを参照してください。 – blerontin

+0

良い仕事;これと同等のフラグをInnoSetupに追加できればいいでしょう! –

1

Innoでは、このチェックをネイティブに行うことはできません。

インストール中に変更されたファイルを置き換えないようにするには、カスタム[Code]を使用してチェックサムを実行し、前回のインストールで事前計算または保存された既知の適切な値と比較する必要があります。

アンインストール中にファイルを削除しないようにするには、そのファイルに対してInno独自のアンインストールを無効にしてから、同じチェックサムをチェックしてから再度削除する必要があります。[Code]

この状況をより適切に処理し、アプリケーションのガイドラインに正しく従うために、ユーザーがセットアップ外で編集できるファイルを保存する方がよいことに注意してください。

関連する問題