2012-05-21 30 views
9

Cách yêu cầu InnoSetup không gỡ cài đặt (văn bản) tệp đã bị người dùng thay đổi (== khác với những tệp được cài đặt bởi InnoSetup)? Hoặc có thể khó khăn hơn: khi cài đặt phiên bản mới hơn một phiên bản hiện tại, InnoSetup nên yêu cầu người dùng ghi đè lên tập tin đã thay đổi, nhưng khi gỡ cài đặt thuần túy, nó sẽ gỡ cài đặt nó mà không hỏi.InnoSetup: không gỡ cài đặt các tệp đã thay đổi

+0

Có thể bạn có thể sử dụng 'UninsNeverUninstall' và sau đó thêm phần '[CODE]' cho 'CurUninstallStepChanged'' usPostUninstall'tất cả các tệp TXT sẽ được kiểm tra cho CRC và sau đó bị xóa nếu CRC bằng hoặc nếu CRC không bằng nhau sẽ được thông báo về các tệp đã thay đổi + đã xóa. – RobeN

+1

Các tệp là gì? Nếu một tập tin cấu hình, nó tốt hơn để cài đặt một tập tin mặc định với một tên khác nhau sau đó sao chép đó vào vị trí của tập tin cấu hình chính nếu nó không tồn tại. Nếu họ là tập tin người dùng, thiết lập không nên chạm vào chúng. – Deanna

Trả lời

6

Gần đây, tôi đã gặp phải sự cố tương tự. Đây là giải pháp của tôi để phát hiện xem tệp văn bản (hồ sơ) đã được thay đổi từ tệp được cài đặt trong lần cài đặt cuối cùng chưa:

Sử dụng ISPP (Inno Setup Pre-Processor) để tạo danh sách tệp văn bản và băm của chúng tại biên dịch thời gian:

[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 

Ở phía trên cùng của "Code" phần tôi xác định một số điều hữu ích:

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

trong mục "Kiểm tra" xử lý sự kiện tôi so sánh băm của trước đó cài đặt và tập tin hiện tại:

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; 

Trong trình xử lý sự kiện "AfterInstall" tôi đánh dấu băm tệp sẽ được lưu trữ trong Đăng ký sau. Bởi vì trong các thử nghiệm của tôi sự kiện đã được kích hoạt ngay cả khi việc di chuyển tệp không thành công (tệp đích là chỉ đọc), tôi so sánh lại băm để tìm hiểu xem việc di chuyển tệp có thành công không:

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

Tôi có thể hỏi khi bạn gọi RegisterPreviousData() không? –

+2

@JulienM: 'RegisterPreviousData' là một chức năng sự kiện được gọi bởi Inno Setup tự động nếu một hàm có tên đó tồn tại. Xem Trợ giúp thiết lập Inno để biết thêm thông tin. – blerontin

+0

Công việc tốt; sẽ là tốt đẹp nếu một lá cờ tương đương với điều này có thể được thêm vào InnoSetup! –

1

Inno không thể thực hiện kiểm tra này một cách tự nhiên.

Để không thay thế tệp đã thay đổi trong quá trình cài đặt, bạn cần sử dụng tùy chỉnh [Code] để thực hiện kiểm tra và so sánh với giá trị tốt đã biết trước đó hoặc được lưu trước đó từ lần cài đặt trước.

Để tránh xóa chúng trong khi gỡ cài đặt, bạn cần phải vô hiệu hóa cài đặt riêng của Inno đối với tệp đó và kiểm tra cùng một kiểm tra trước khi xóa chúng, lại trong [Code].

Lưu ý rằng tốt hơn là giữ bất kỳ tệp nào mà người dùng có thể chỉnh sửa bên ngoài thiết lập để xử lý tình huống này tốt hơn và tuân thủ chính xác các nguyên tắc của ứng dụng.

Các vấn đề liên quan