2

在我的安装程序中,我从不存储时间/日期属性的档案中提取文件,因此当它们被提取时,最后修改日期设置为当前日期。我想将其设置为存档文件的最后修改日期,但我不知道如何。我尝试使用此处此处的代码片段,但虽然它没有给出任何错误,但它不适用于更改时间。需要在文件夹中更改 * .* 的上次修改日期。

另外,如果用户取消设置并开始回滚更改,我需要在哪里删除这些文件?我已经在 UninstallDelete 中处理了它,但如果用户取消设置则不会。

编辑:忽略第二部分,我实际上是在我在这里发布后不久就想出来的。将我自己的 CleanUp() 添加到 DeinitializeSetup() 并检查卸载程序注册表项。

这是我尝试将其添加到的代码部分:

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

2 回答 2

2

要通过某个文件的 LastWriteTime 更改指定目录中所有文件的最后修改时间(我们现在称之为 LastWriteTime),请在提取文件后使用以下代码。您可以按照commented version这篇文章的先前版本,但请注意,我在那里有错误(混合时间参数和未使用的文件标志参数),但重点仍然存在。

另请注意,此代码适用于 InnoSetup 的 ANSI 版本。如果您需要将此用于 Unicode 版本,则应将CreateFile函数 import 定义为,CreateFileW而不是使用thisCreateFileA中建议的技巧。kobikpost

[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 'CreateFileA@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; 
  external 'CloseHandle@kernel32.dll stdcall';
function SetFileTime(hFile: THandle; const lpCreationTime, lpLastAccessTime, 
  lpLastWriteTime: TFileTime): BOOL; 
  external 'SetFileTime@kernel32.dll 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 的源文件的名称。第二个参数是文件将被源文件修改其 LastWriteTime 值的目录(不要忘记在目标文件夹参数中包含尾部反斜杠):

ModifyLastWriteTime('c:\SourceFile.xxx', 'c:\TargetFolder\')
于 2012-04-15T14:59:20.373 回答
0

关于第二个问题,您可以在一个名为的过程中删除已提取的文件

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

正如 chm 中的解释,Pascal 脚本:事件函数部分

关于第一个问题,我建议您使用 inno setup [files] 部分而不是从存档中提取。您可能可以将此存档解压缩到本地文件夹(因此从您这边,在编译之前,将此本地文件夹添加到 [files]。但我可能误解了您对文件修改日期的要求。

于 2012-04-14T09:57:50.240 回答