首页 > 解决方案 > 用于系统文件功能的 Delphi 跨平台系统实用程序

问题描述

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

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

我已经用谷歌搜索了这些,但我看到的点击只涉及 Windows 功能。一些命中表明 Free Pascal 提供了一个被描述为跨平台的TProcess类和ExecuteProcess()、、RunCommand()和过程。OpenDocument()

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

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

标签: delphifiremonkey

解决方案


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

对于您的最后一点,您可以在单元中找到解决方案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 函数的结果,ShellExecute并且System.

对于您的第一点,我有一个仅适用于 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;

推荐阅读