2012-04-13 30 views
2

私のインストーラでは、時刻/日付属性を格納していないアーカイブからファイルを抽出します。抽出された最後の修正日は現在の日付に設定されます。私はそれをアーカイブファイルの最後の修正日に設定したいと思いますが、私はどのように把握できません。 herehereのコードを試してみましたが、エラーは発生しませんでしたが、時間を変更しても機能しませんでした。最終変更日は、フォルダ内の*。*に対して変更する必要があります。Inno Setup:1つのファイルから変更された時刻を読み取り、それを使ってディレクトリ全体のファイルの時刻を設定します。

また、ユーザーがセットアップをキャンセルして変更をロールバックする場合、これらのファイルを削除するにはどうすればよいですか?私はUninstallDeleteで世話をしましたが、ユーザーが設定をキャンセルした場合は処理しません。

EDIT:2番目の部分を無視して、私がここに投稿した直後に実際に分かった。 DeinitializeSetup()に自分自身のCleanUp()を追加して、アンインストーラのレジストリキーをチェックしました。ここで

は、私はそれを追加しようとしているコードのセクションです:あなたが呼ばれる手順で抽出されたファイルを削除することができ、2つ目の質問について

procedure VolExtract(VWorld: String); 
var 
    ResultCode: Integer; 
    VPath: String; 
begin 
    // Files are extracted to {app}\VWorld\One, {app}\VWorld\Two, etc. 
    VPath := ExpandConstant('{app}\' + VWorld); 
    WizardForm.FilenameLabel.Caption := DriveLetter + VWorld + '\one.vol'; 
    if Exec(ExpandConstant('{tmp}\volextract.exe'), '"' + DriveLetter + VWorld + '\one.vol" "' + VPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then 
    begin 
    // Yep, it executed successfully 
    WizardForm.FilenameLabel.Caption := DriveLetter + VWorld + '\two.vol'; 
    if Exec(ExpandConstant('{tmp}\volextract.exe'), '"' + DriveLetter + VWorld + '\two.vol" "' + VPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then 
    begin 
     // Next 
     WizardForm.FilenameLabel.Caption := DriveLetter + VWorld + '\three.vol'; 
     if Exec(ExpandConstant('{tmp}\volextract.exe'), '"' + DriveLetter + VWorld + '\three.vol" "' + VPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then 
     begin 
     // Next 
     WizardForm.FilenameLabel.Caption := DriveLetter + VWorld + '\four.vol'; 
     Exec(ExpandConstant('{tmp}\volextract.exe'), '"' + DriveLetter + VWorld + '\four.vol" "' + VPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); 
     end; 
    end; 
    end; 
    if ResultCode <> 0 then 
    begin 
    // Handle Fail 
    CDFound := False; 
    MsgBox(CustomMessage('FileErr'), mbInformation, MB_OK); 
    WizardForm.Close; 
    end; 
end; 

答えて

2

最後のファイルを変更するには特定のファイルのLastWriteTimeで指定されたディレクトリにあるすべてのファイルの変更時刻(今のところLastWriteTimeとしましょう)は、ファイルを抽出した後に次のコードを使用してください。

このコードは、InnoSetupのANSIバージョン用であることに注意してください。これをUnicodeバージョンに使用する必要がある場合は、を定義する必要があります関数をCreateFileAの代わりにCreateFileWとしてインポートするか、kobikで提案されているテクニックをpostに使用してください。

[code] 
const 
    OPEN_EXISTING = 3; 
    FILE_SHARE_WRITE = 2; 
    GENERIC_WRITE = $40000000; 
    INVALID_HANDLE_VALUE = 4294967295; 

function CreateFile(lpFileName: string; dwDesiredAccess, dwShareMode, 
    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes: DWORD; 
    hTemplateFile: THandle): THandle; 
    external '[email protected] stdcall'; 
function CloseHandle(hObject: THandle): BOOL; 
    external '[email protected] stdcall'; 
function SetFileTime(hFile: THandle; const lpCreationTime, lpLastAccessTime, 
    lpLastWriteTime: TFileTime): BOOL; 
    external '[email protected] stdcall'; 

function FileSetTime(const AFileName: string; const ACreationTime, 
    ALastAccessTime, ALastWriteTime: TFileTime): Boolean; 
var 
    FileHandle: THandle; 
begin 
    Result := False; 
    FileHandle := CreateFile(AFileName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, 
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    if FileHandle <> INVALID_HANDLE_VALUE then 
    try 
    Result := SetFileTime(FileHandle, ACreationTime, ALastAccessTime, 
     ALastWriteTime); 
    finally 
    CloseHandle(FileHandle); 
    end; 
end; 

procedure ModifyLastWriteTime(const ASourceFile, ATargetFolder: string); 
var 
    FindRec: TFindRec; 
    LastWriteTime: TFileTime; 
begin 
    if FindFirst(ASourceFile, FindRec) then 
    begin 
    LastWriteTime := FindRec.LastWriteTime; 
    if FindFirst(ATargetFolder + '*.*', FindRec) then 
    try 
     repeat 
     if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then 
      FileSetTime(ATargetFolder + FindRec.Name, FindRec.CreationTime, 
      FindRec.LastAccessTime, LastWriteTime); 
     until 
     not FindNext(FindRec); 
    finally 
     FindClose(FindRec); 
    end; 
    end; 
end; 

そしてその使用法。 ModifyLastWriteTimeプロシージャの最初のパラメータは、LastWriteTimeが取得されるソースファイルの名前です。 `CancelButtonClick`することができますで

ModifyLastWriteTime('c:\SourceFile.xxx', 'c:\TargetFolder\') 
+1

パーフェクト!私は今すぐこれを試しに行くだろう、それがうまくいくなら私は先に進み、それを答えにするだろう。どうもありがとうございました :) – user477276

0

Procedure CancelButtonClick(CurPageID: Integer; Var Cancel, Confirm: Boolean); 
Begin 
End; 

chmで説明されているように、パスカルスクリプティング:イベント関数

最初の質問については、アーカイブから抽出する代わりに[ファイル]セクションを設定しないでください。このアーカイブをローカルフォルダに展開することもできます(コンパイルする前に、ローカルフォルダを[ファイル]に追加することもできます)。

+1

:2つ目のパラメータは、ファイルは、ソースファイル(ターゲットフォルダパラメータにバックスラッシュを持っていることを忘れないでください)によって彼らのLastWriteTime値を変更し得るものではディレクトリです'Confirm'と' Cancel'パラメータをTrueに設定すると、このイベントのコードが完了した後に 'Exit setup?'ダイアログが表示されます。この確認ダイアログを拒否できるので、これは適切な場所ではありません。 – TLama

+0

ええ、それはすでにCancelButtonClickの私の理解でした。私は実際にこの質問を投稿した直後にこの部分を理解することができましたが、まだ更新する機会はありませんでした。私はレジストリのアンインストーラキーのチェックを付けてDeinitializeSetup()にCleanUp()プロシージャを追加しました。 – user477276

関連する問題