2014-03-28 26 views
0

我有一個Inno安裝腳本,我需要在安裝或替換特定文件之前執行自定義操作。如何檢測文件是否要安裝(或替換)?

documentation狀態:

如果安裝程序已經確定它不應該被處理記錄A BeforeInstallAfterInstall函數沒有被調用。

所以我想我可以用BeforeInstall指定安裝文件之前,應當做什麼,但似乎Inno Setup的需要安裝的文件或不決定調用BeforeInstall功能後,所以這函數實際上每次都被調用。

如何在安裝文件之前執行操作,但如果文件未安裝(例如,因爲其版本未更改),該如何執行操作?

編輯:

下面的代碼的相關部分:

... 
[Files] 
... 
Source: "..\bin\{#BuildConfig}\FooBar.dll"; DestDir: "{app}"; Flags: uninsrestartdelete; BeforeInstall: PrepareInstallFooBar 

... 
[Code] 
... 
procedure PrepareInstallFooBar(); 
begin 
    Log(Format('BeforeInstall: %s', [CurrentFileName])); 
    ... 
end; 

... 

下面是該日誌中顯示:

... 
2014-03-28 10:40:46.778 BeforeInstall: {app}\FooBar.dll 
2014-03-28 10:40:46.778 -- File entry -- 
2014-03-28 10:40:46.778 Dest filename: C:\Users\tom\AppData\Local\MyApp\bin\FooBar.dll 
2014-03-28 10:40:46.778 Time stamp of our file: 2014-03-28 10:35:10.000 
2014-03-28 10:40:46.778 Dest file exists. 
2014-03-28 10:40:46.778 Time stamp of existing file: 2014-03-28 10:35:10.000 
2014-03-28 10:40:46.778 Version of our file: 1.0.0.0 
2014-03-28 10:40:46.778 Version of existing file: 1.0.0.0 
2014-03-28 10:40:46.778 Same version. Skipping. 
... 
+0

是什麼讓你認爲Inno Setup決定是否在'BeforeInstall'方法執行後安裝文件? ['源代碼'](https://github.com/jrsoftware/issrc/blob/is-5_5_4/Projects/Install.pas#L1622)顯示了其他內容。只有當條件通過時,纔會注意'ShouldProcessFileEntry'函數的條件以及隨後調用NotifyBeforeInstallFileEntry方法。你能告訴我們一些具體的案例嗎? – TLama

+0

@TLama,我在'BeforeInstall'函數的日誌中寫了一行,我可以看到它總是在IS決定跳過文件之前執行。 –

+0

@TLama,我發佈了代碼和日誌文件的相關部分 –

回答

0

因爲我不能讓Inno Setup的行爲方式我想,我最終自己在Check函數中檢查了自己的版本:

... 
[Files] 
Source: "..\bin\{#BuildConfig}\FooBar.dll"; DestDir: "{app}"; Flags: uninsrestartdelete; Check: ShouldInstallFooBar; BeforeInstall: BeforeInstallFooBar; 
... 

[Code] 
function ShouldInstallFooBar() : Boolean; 
var 
    fooBarTempPath: String; 
    installedFooBarPath: String; 
    newFooBarVersion: String; 
    installedFooBarVersion: String; 
begin 
    installedFooBarPath := ExpandConstant('{app}\FooBar.dll'); 
    if FileExists(installedFooBarPath) then begin 
    // Get version of currently installed file 
    if GetVersionNumbersString(installedFooBarPath, installedFooBarVersion) then begin 
     Log('File already exists; version = ' + installedFooBarVersion); 
     // Extract new file and get its version 
     ExtractTemporaryFile('FooBar.dll'); 
     fooBarTempPath := ExpandConstant('{tmp}\FooBar.dll'); 
     if GetVersionNumbersString(fooBarTempPath, newFooBarVersion) then begin 
     Log('New version = ' + newFooBarVersion); 
     if newFooBarVersion <> installedFooBarVersion then begin 
      fooBarShouldBeInstalled := true; 
     end else begin 
      fooBarShouldBeInstalled := false; 
     end; 
     end else begin 
     // Failed to get version for new file; assume it's different and install it 
     fooBarShouldBeInstalled := true; 
     end; 
    end else begin 
     // Failed to get version for existing file; assume it's different and install the new one 
     fooBarShouldBeInstalled := true; 
    end; 
    end else begin 
    // File doesn't exist, install it 
    fooBarShouldBeInstalled := true; 
    end; 
    Result := fooBarShouldBeInstalled; 
end; 

procedure BeforeInstallFooBar(); 
begin 
    // what I need to do before the file is installed... 
end; 

... 
+0

沒有直接的方式來實現你所要求的東西,所以像這樣的解決方法是唯一的方法。但是,您當前的代碼可以用較舊的代碼覆蓋較新的版本。您不能僅比較版本字符串的差異。如果它們不同,你應該確定哪一個更新。 – TLama

+0

@TLama,其實這就是我想要的行爲;如果我安裝我的應用程序的舊版本,我希望這個文件被替換。 –

+0

在這種情況下,您可能應該無條件安裝它。用戶可能會再次運行安裝程序以嘗試修復該文件,或者您可能已修改該文件並忘記增加版本號。 – Miral