Delphi 系统文件功能的跨平台系统实用程序

Delphi cross-platform system utilities for system file functions

我正在将 Delphi 10.3 VCL 应用程序迁移到 Firemonkey。不使用 GUI 的单元无需任何修改即可编译,但使用下面提到的 Windows-特定系统函数的单元除外。

任何人都可以指出 Delphi/Firemonkey 10.3 中的跨平台系统文件实用程序或替代解决方法,以执行完成我的项目所需的以下操作:

我有 Googled 个,但我看到的命中率仅涉及 Windows 个函数。一些点击表明 Free Pascal 提供了 TProcess class 和 ExecuteProcess()RunCommand()OpenDocument() 过程,这些过程被描述为跨平台的。

关于时间戳,可以使用 FindFirstFindNext 函数获取这些时间戳,然后在返回的 TSearchRec 中读取时间戳。但是我没有找到如何在 FMX 版本中设置时间戳,这是我在 VCL 版本中使用相关的 Win API 函数完成的。

我不是在征求关于多个可能选项中最佳选项的意见或建议,而是针对有关 Delphi 10.3 对基本系统功能的跨平台支持的特定问题的事实回答人们希望在任何成熟的 GUI OS 中找到它,例如 Windows 和基于 Unix 的 OS。在将问题发布到 Whosebug 之前,我在 Delphi 帮助系统和 Google 上搜索了答案但没有成功。该线程中的第一个答案就是这样做的。我很感激。

你问的四点在我看来对于一个问题来说差异太大了。

对于最后一点,您在单元 System.IOUtils.TFile:

中找到了解决方案
class function GetCreationTime(const Path: string): TDateTime; 
class procedure SetCreationTime(const Path: string; const CreationTime: TDateTime); 
class function GetLastAccessTime(const Path: string): TDateTime;
class procedure SetLastAccessTime(const Path: string; const LastAccessTime: TDateTime);
class function GetLastWriteTime(const Path: string): TDateTime;
class procedure SetLastWriteTime(const Path: string; const LastWriteTime: TDateTime); 

对于您的第 1 点到第 3 点,Delphi 的 RTL 中还没有解决方案。

对于你的第 2 点和第 3 点,我已经实现了我自己的适用于 Windows 和 MacOS 的解决方案:

uses
  {$IFDEF MSWINDOWS}
  WinApi.ShellApi; 
  {$ENDIF}
  {$IFDEF MACOS}
  Posix.Stdlib;
  {$ENDIF}

class procedure TApiHelpers.OpenFileByOS(const FileName: string);
begin
  {$IFDEF MSWINDOWS}
  ShellExecute(0, 'open', PChar(FileName), nil, nil, SW_SHOW);
  {$ENDIF}
  {$IFDEF MACOS}
  _system(PAnsiChar(UTF8String('open "' + FileName + '"')));
  {$ENDIF}
end;

对于最终解决方案,您必须检查并处理 API 函数 ShellExecuteSystem.

的结果

关于你的第一点,我有一个解决方案只适用于 windows:

  function GetExtImg(const FileName: string; out ExtImg: IExtractImage): boolean;
  var
    Desktop, Target: IShellFolder;
    PIDL: PItemIDList;
    Attr, Eaten: DWORD;
    res: HResult;
  begin
    OleCheck(SHGetDesktopFolder(Desktop));
    OleCheck(Desktop.ParseDisplayName(0, nil, PChar(ExcludeTrailingPathDelimiter(ExtractFilePath(FileName))), Eaten, PIDL, Attr));
    try
      OleCheck(Desktop.BindToObject(PIDL, nil, IShellFolder, Target));
    finally
      fMalloc.Free(PIDL);
    end;
    OleCheck(Target.ParseDisplayName(0, nil, PChar(ExtractFileName(FileName)), Eaten, PIDL, Attr));
    try
      Result := S_OK = Target.GetUIObjectOf(fOwnerForm[0], 1, PIDL, IExtractImage, nil, ExtImg);
    finally
      fMalloc.Free(PIDL);
    end;
  end;