2012-05-21 10 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]을 사용하여 체크섬을 수행하고 이전 설치에서 사전 계산되거나 저장 한 알려진 올바른 값과 비교해야합니다.

제거 중에 제거하지 않으려면 [Code]에서 해당 파일에 대한 Inno의 자체 제거를 비활성화하고 제거하기 전에 동일한 체크섬을 확인해야합니다.

이 상황을 더 잘 처리하고 응용 프로그램 가이드 라인을 올바르게 준수하려면 사용자가 설정 외부에서 편집 할 수있는 파일을 유지하는 것이 좋습니다.

관련 문제