如何在Delphi中使用Window API更改MSWindows 10中的日期創建或其他文件

MSWindows 10 Enterprise 1909(內部版本18363.904)以32/64位編譯的
RAD Studio Delphi 10.3.3 
VCL 工程 歡迎加入Delphi開發局QQ羣:32422310

注意:DateTime在MSExplorer上似乎有點差異-可能是因爲有必要在“日期”上添加“ TIIME”-請看...(泰山老父僅測試了文件的日期創建)注意。

unit uFormMain;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Vcl.ComCtrls;

type
  TfrmFormMain = class(TForm)
    btnOpenDialogFiles: TButton;
    OpenDialog1: TOpenDialog;
    Memo1: TMemo;
    DateTimePicker1: TDateTimePicker;
    Label1: TLabel;
    procedure btnOpenDialogFilesClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
  end;

var
  frmFormMain: TfrmFormMain;

implementation

{$R *.dfm}
// uses
// System.DateUtils;

//

{ to do in real case:
  //
  1) verify file attributes, like: hidden, system, protected, etc... else, boommmm!
  //
  2) verify is the dates is not the same before changing!
  //
  3) always works like if any error can happens! always!
  //
}

const
  // https://docs.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants
  // The valid access rights for files and directories include the DELETE, READ_CONTROL,
  // WRITE_DAC, WRITE_OWNER, and SYNCHRONIZE standard access rights. The following table lists
  // the access rights that are specific to files and directories.
  FILE_WRITE_ATTRIBUTES = $0100;

var
  // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-win32_file_attribute_data
  // Contains attribute information for a file or directory. The GetFileAttributesEx function uses this structure.
  lMyFileInfo: WIN32_FILE_ATTRIBUTE_DATA;

procedure prcFileInfo(lFileName: string);
var
  SystemTime: TSystemTime;
  // FileTime  : TFileTime;
begin
  // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesexa
  // Retrieves attributes for a specified file or directory.
  try
    GetFileAttributesEx(PWideChar(lFileName), GetFileExInfoStandard, @lMyFileInfo);
    //
    FileTimeToSystemTime(lMyFileInfo.ftCreationTime, SystemTime);
    frmFormMain.Memo1.Lines.Add(Format('FileName: Creation Date %s', [FormatDateTime('dd/mm/yyyy hh:mm;ss', SystemTimeToDateTime(SystemTime))])); { _FILETIME }
    //
    FileTimeToSystemTime(lMyFileInfo.ftLastAccessTime, SystemTime);
    frmFormMain.Memo1.Lines.Add(Format('FileName: Last Access %s', [FormatDateTime('dd/mm/yyyy hh:mm;ss', SystemTimeToDateTime(SystemTime))])); { _FILETIME }
    //
    FileTimeToSystemTime(lMyFileInfo.ftLastWriteTime, SystemTime);
    frmFormMain.Memo1.Lines.Add(Format('FileName: Last Write %s', [FormatDateTime('dd/mm/yyyy hh:mm;ss', SystemTimeToDateTime(SystemTime))])); { _FILETIME }
    //
    frmFormMain.Memo1.Lines.Add(Format('FileName: Attibutes = %d', [lMyFileInfo.dwFileAttributes])); { Cardinal - see values valids in Microsoft }
    //
    // https://docs.microsoft.com/pt-br/dotnet/api/microsoft.visualstudio.shell.interop.vsqeqs_file_attribute_data.nfilesizehigh?view=visualstudiosdk-2017
    // https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataa
    frmFormMain.Memo1.Lines.Add(Format('FileName: FileSizeHigh = %d', [lMyFileInfo.nFileSizeHigh])); { Cardinal -- needs do convertion }
    frmFormMain.Memo1.Lines.Add(Format('FileName: FileSizeLow = %d', [lMyFileInfo.nFileSizeLow]));   { Cardinal }
  except
    on E: Exception do
      ShowMessage('Error on prcFileInfo()' + sLineBreak + E.Message);
  end;
end;

procedure SetFileCreationTime(const FileName: string; const DateTime: TDateTime);
var
  Handle    : THandle;
  SystemTime: TSystemTime;
  FileTime  : TFileTime;
begin
  {
    Handle := INVALID_HANDLE_VALUE;
    //
    SystemTime.wYear         := 0;
    SystemTime.wMonth        := 0;
    SystemTime.wDayOfWeek    := 0;
    SystemTime.wDay          := 0;
    SystemTime.wHour         := 0;
    SystemTime.wMinute       := 0;
    SystemTime.wSecond       := 0;
    SystemTime.wMilliseconds := 0;
    //
    FileTime.dwLowDateTime  := 0;
    FileTime.dwHighDateTime := 0;
  }
  //
  // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-opening-files
  // The CreateFile function can create a new file or open an existing file.
  // You must specify the file name, creation instructions, and other attributes.
  // When an application creates a new file, the operating system adds it to the specified directory.
  //
  Handle := CreateFile(PChar(FileName),  { }
    FILE_WRITE_ATTRIBUTES,               { }
    FILE_SHARE_READ or FILE_SHARE_WRITE, { }
    nil,                                 { }
    OPEN_EXISTING,                       { }
    FILE_ATTRIBUTE_NORMAL,               { }
    0 { } );
  //
  if (Handle = INVALID_HANDLE_VALUE) then
    RaiseLastOSError;
  //
  try
    // http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/SysUtils_DateTimeToSystemTime.html
    // Converts a TDateTime value into the Win32 API's system time type.
    DateTimeToSystemTime(DateTime, SystemTime);
    //
    // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetofiletime
    // Converts a system time to file time format.
    // System time is based on Coordinated Universal Time (UTC).
    if not SystemTimeToFileTime(SystemTime, FileTime) then
      RaiseLastOSError;
    //
    // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime
    // Sets the date and time that the specified file or directory was created,
    // last accessed, or last modified.
    if not SetFileTime(Handle, @FileTime, nil, nil) then
      RaiseLastOSError;
  finally
    CloseHandle(Handle);
  end;
end;

procedure TfrmFormMain.btnOpenDialogFilesClick(Sender: TObject);
begin
  Memo1.Clear;
  //
  if OpenDialog1.Execute() and (not(OpenDialog1.FileName = '')) then
    begin
      try
        Memo1.Lines.Add(Format('FileName: %s', [ExtractFileName(OpenDialog1.FileName)]));
        Memo1.Lines.Add('');
        Memo1.Lines.Add(Format('Absolute Path: %s', [ExtractFilePath(OpenDialog1.FileName)]));
        Memo1.Lines.Add('');
        //
        prcFileInfo(OpenDialog1.FileName);
        //
        Memo1.Lines.Add('');
        //
        // IMPORTANT:
        // in fact, when looking in MSExplorer the creation-date is different some seconds, minutes, or hour! Needs verify this!
        //
        SetFileCreationTime(OpenDialog1.FileName, DateTimePicker1.Date);
        //
        prcFileInfo(OpenDialog1.FileName);
        //
        Memo1.Lines.Add('');
        //
        Memo1.Lines.Add('The creating date of file was successfully changed!' + sLineBreak + 'It''s working in MSWindows 10 Enterprise build 1909 with KIS 2020 antivirus active!');
      except
        on E: Exception do
          ShowMessage('error' + sLineBreak + E.Message);
      end;
    end;
end;

procedure TfrmFormMain.FormCreate(Sender: TObject);
begin
  Self.Width           := 860;
  Self.Height          := 380;
  DateTimePicker1.Date := now;
end;

end.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章