如何告訴InnoSetup不要卸載(文本)由用戶更改的文件(==與InnoSetup安裝的文件不同)?或者更難:當在現有的版本上安裝新版本時,InnoSetup應該詢問用戶是否覆蓋已更改的文件,但是在純卸載時,它應該在不詢問的情況下卸載它。InnoSetup:不要卸載已更改的文件
回答
我最近有一個類似的問題。這是我的解決方案,用於檢測文本文件(配置文件)是否已從上次安裝運行期間安裝的文本文件(配置文件)更改爲:
使用ISPP(Inno Setup Pre-Processor)創建文本文件及其哈希列表編譯時間:
[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
在「代碼」部分頂部我定義了一些有用的東西:
[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;
在「檢查」事件處理程序我比較以前的散列安裝和當前文件:
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;
我可以問你什麼時候調用RegisterPreviousData()? –
@JulienM:如果存在具有該名稱的函數,則「RegisterPreviousData」是由Inno Setup自動調用的事件函數。有關更多信息,請參閱Inno Setup幫助。 – blerontin
良好的工作;如果一個相當於這個的標誌可以被添加到InnoSetup中會更好! –
Inno無法在本地執行此檢查。
要在安裝過程中不替換已更改的文件,您需要使用自定義[Code]
來執行校驗和,並與預先計算或從以前的安裝中保存的已知良好值進行比較。
爲避免在卸載過程中將其刪除,您需要先禁用Inno自己的卸載,然後在刪除它們之前檢查相同的校驗和,再次在[Code]
。
請注意,最好保留用戶可以在設置之外編輯的任何文件,以更好地處理這種情況並正確遵守應用程序指南。
- 1. 更改文件的文本,而不會破壞卸載過程
- 2. 不要使用WSPBuilder卸載文件
- 3. 如何強制InnoSetup創建卸載日誌文件
- 4. 在InnoSetup中添加卸載圖標
- 5. InnoSetup卸載提問信息 - Pascal編碼
- 6. 只下載已更改的文件git
- 7. InnoSetup:「文件的卷已被外部改變」
- 8. 更改頁面後卸載事件
- 9. InstallShield2010 XML文件修改和卸載更改
- 10. MSI不卸載.dll文件
- 11. 將Git中的更改卸載到特定文件中
- 12. 備份文件並使用InnoSetup進行卸載時恢復它們?
- 13. Tabcontrol - 選擇更改加載/卸載
- 14. RUnit測試已卸載的軟件包
- 15. 拆卸,更改和組裝DLL文件
- 16. Relay-Modern試圖更新已經卸載的組件`Relay(Songs)`
- 17. Git - 查看已更改的文件,即使已刪除更改
- 18. InnoSetup如何確定卸載程序窗口的HWND?
- 19. 文件位置已更改?
- 20. 卸載Cornerstone中的文件
- 21. 如何在InnoSetup中更改安裝目標文件夾權限?
- 22. 如何更改InnoSetup中的下載路徑?
- 23. 如何更改InnoSetup頁面的順序?
- 24. 在卸載時刪除已安裝文件的推薦庫/宏
- 25. InstallShield:在卸載時刪除已安裝的文件
- 26. 卸載Git中所有已刪除的文件
- 27. 卸載已使用CUDA內存的mex文件時,MATLAB崩潰
- 28. 使用Inno Setup卸載已創建的日誌文件
- 29. bat文件來卸載已安裝的應用程序
- 30. InnoSetup中的文件選擇
也許你可以使用'UninsNeverUninstall'標誌,然後爲'CurUninstallStepChanged'' usPostUninstall'添加一個'[CODE]'部分,其中所有的TXT文件將檢查CRC,然後刪除,如果CRC相等或者CRC不等於用戶將被通知有關更改的文件+詢問文件是否應該刪除。 – RobeN
這些文件是什麼?如果是配置文件,最好使用不同的名稱安裝默認文件,然後將其複製到主配置文件中不存在的位置。如果它們是用戶文件,則安裝程序根本不應觸摸它們。 – Deanna