从一个文件中读取修改的时间,并使用它来设置整个目录中文件的时间 [英] Read modified time from one file and use it to set the time for files in a whole directory

查看:94
本文介绍了从一个文件中读取修改的时间,并使用它来设置整个目录中文件的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my installer I'm extracting files from archives that don't store time/date attributes, so when they're extracted the last modified date is set to the current date. I would like to set it to the last modified date of the archive file but I can't figure out how. I tried using pieces of the code from here and here but while it didn't give any errors, it didn't work for changing the time. Last modified date would need to be changed for * .* in a folder.

此外,如果用户取消设置并且开始回滚更改,那么我需要挂接到哪里删除这些文件?我已经在UninstallDelete中解决了这个问题,但是如果用户取消安装,则不会解决.

无视第二部分,实际上我在这里发布后不久就弄清楚了.将我自己的CleanUp()添加到DeinitializeSetup()中,并检查卸载程序的注册表项.

Disregard the second part, I actually figured it out shortly after I posted here. Added my own CleanUp() to DeinitializeSetup() with a check for the uninstaller registry key.

这是我要添加到的代码部分:

Here is the section of code I'm trying to add it to:

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;

推荐答案

要通过特定文件的LastWriteTime更改指定目录中所有文件的上次修改时间(现在将其称为LastWriteTime).提取文件后.您可以按照本文上一个版本的 commented version 进行操作,但请注意,我在此处遇到了一些错误(混合时间参数和未使用的文件标志参数),但要点仍然存在.

To change the last modified time (let's call it LastWriteTime for now) for all files from a specified directory by the LastWriteTime of a certain file, use the following code after you have your files extracted. You can follow the commented version of the previous version of this post, but note that I've had bugs there (mixed time parameters and unused file flag parameter), but the point remains.

还请注意,此代码用于ANSI版本的InnoSetup.如果需要将其用于Unicode版本,则应将CreateFile函数导入定义为CreateFileW而不是CreateFileA,或使用 post 中.

Also note that this code is for ANSI version of InnoSetup. If you need to use this for Unicode version, you should define the CreateFile function import as CreateFileW instead of CreateFileA or use the trick suggested by kobik in this 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 '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值(不要忘记在目标文件夹参数中带有尾部反斜杠):

And the usage. The first parameter of the ModifyLastWriteTime procedure is the name of the source file from which the LastWriteTime is taken. The second parameter is the directory in what the files will get modified their LastWriteTime values by the source file (don't forget to have the trailing backslash in the target folder parameter):

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

这篇关于从一个文件中读取修改的时间,并使用它来设置整个目录中文件的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆