2

我有运行良好的 Inno Setup 脚本,但我需要在其中加入一个功能。我想在任何安装过程中实现的目标如下:

  1. 查明是否存在两个文件(完成)
  2. 如果它们都存在,则继续安装并覆盖它们(完成)
  3. 如果两个文件都丢失,则将新文件安装/复制到目标文件夹(完成)
  4. 如果一个存在而另一个缺失,则获取现有文件的创建日期。创建安装丢失的文件,但将创建日期和时间设置为与已经存在的文件完全相同(需要帮助)

我已经搜索了整个论坛,唯一接近这个的答案就是这个

任何帮助将不胜感激。

谢谢。

4

1 回答 1

1

这是一组可以获取和设置文件时间的函数:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

const
  OPEN_EXISTING = 3;  
  GENERIC_READ = $80000000;
  FILE_WRITE_ATTRIBUTES = $0100;
  INVALID_HANDLE_VALUE = 4294967295;

type
  TFileTimes = record
    CreationTime: TFileTime;
    LastWriteTime: TFileTime;
    LastAccessTime: TFileTime;
  end;

function CreateFile(lpFileName: string; dwDesiredAccess, dwShareMode,
  lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes: DWORD;
  hTemplateFile: THandle): THandle; 
  external 'CreateFile{#AW}@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; 
  external 'CloseHandle@kernel32.dll stdcall';
function GetFileTime(hFile: THandle; out lpCreationTime, lpLastAccessTime,
  lpLastWriteTime: TFileTime): BOOL;
  external 'GetFileTime@kernel32.dll stdcall';
function SetFileTime(hFile: THandle; const lpCreationTime, lpLastAccessTime, 
  lpLastWriteTime: TFileTime): BOOL; 
  external 'SetFileTime@kernel32.dll stdcall';

function TryGetFileTimes(const FileName: string; out FileTimes: TFileTimes): Boolean;
var
  FileHandle: THandle;
  CreationTime: TFileTime;
  LastWriteTime: TFileTime;
  LastAccessTime: TFileTime;
begin
  Result := False;

  FileHandle := CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, 0);
  if FileHandle <> INVALID_HANDLE_VALUE then
  try
    Result := Boolean(GetFileTime(FileHandle, CreationTime, LastAccessTime, 
      LastWriteTime));
    if Result then
    begin
      FileTimes.CreationTime := CreationTime;
      FileTimes.LastWriteTime := LastWriteTime;
      FileTimes.LastAccessTime := LastAccessTime;
    end;
  finally
    CloseHandle(FileHandle);
  end;
end;

function SetFileTimes(const FileName: string; const FileTimes: TFileTimes): Boolean;
var
  FileHandle: THandle;
begin
  Result := False;

  FileHandle := CreateFile(FileName, FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, 0);
  if FileHandle <> INVALID_HANDLE_VALUE then
  try
    Result := Boolean(SetFileTime(FileHandle, FileTimes.CreationTime,
      FileTimes.LastAccessTime, FileTimes.LastWriteTime));
  finally
    CloseHandle(FileHandle);
  end;
end;

这是它们可能的用法:

var
  FileTimes: TFileTimes;
begin
  if TryGetFileTimes('C:\TheFile.xxx', FileTimes) then
  begin
    if FileCopy('C:\TheNewFile.xxx', 'C:\TheFile.xxx', False) then
      SetFileTimes('C:\TheFile.xxx', FileTimes);
  end;
end;
于 2013-11-05T13:21:49.833 回答