【问题标题】:Open file in OS X在 OS X 中打开文件
【发布时间】:2015-03-04 15:32:47
【问题描述】:

在Delphi中,我想在OS X中打开一个文件,我的做法如下:

const
  Filename = 'test.bmp';

procedure SaveAndOpen;
begin
  Chart.SaveToBitmapFile(Filename);
  {$IFDEF MSWINDOWS}
  ShellExecute(0, 'open', Filename, '', '', SW_Normal);
  {$ELSE}
  _System(Filename);
  {$ENDIF}
end;

但是什么也没发生。我做错了什么?

【问题讨论】:

  • 尝试使用_System(PAnsiChar('open ' + Filename));
  • 谢谢,它有效! :-) 另一个问题,但不重要:有没有办法使用 Unicode 文件名?
  • 肯定有比_System更好的东西吗?对于 Unicode,你不会传递 UTF-8 数据吗?
  • @DavidHeffernan 我不知道 POSIX 标准是否需要 _system() 内的 UTF8。我认为有一个用于打开文件的 OS X API,但我没有找到好的文档。
  • @RRUZ 你确定系统和ANSI?毕竟 ANSI 特别是 Windows。在典型的现代 *nix 系统上,char* 将采用 UTF-8 编码。

标签: macos delphi firemonkey


【解决方案1】:

Embarcadero 的 Malcolm Groves 的这篇文章涵盖了这个主题:Opening files and URLs in default applications in OS X

总而言之,您所需要的就是:

uses
  Macapi.Appkit,       // for NSWorkspace
  Macapi.Foundation;   // for NSSTR
....
var
  Workspace: NSWorkspace; // interface, no need for explicit destruction
....
Workspace := TNSWorkspace.Create;
Workspace.openFile(NSSTR(FileName));

为了完整起见,如果您希望打开 URL 而不是文件,则改为调用 openURL

Workspace.openURL(NSSTR(URL));

关于您的 Windows 代码,我建议不要使用 ShellExecute。该功能没有合理的错误报告。使用 ShellExecuteEx 代替它。

最后,您可能应该将这个功能抽象出来,以便您的程序的其他部分可以重用它。你想尽可能少写IFDEF

【讨论】:

  • 非常感谢您的帮助!我已经应用了所有改进建议并创建了一个应该涵盖所有情况的功能。 pastebin.com/TyMTMStr(我将它用于 OpenSource,因此代码完美且通用对我来说很重要)。如果您有更多改进建议,请告诉我。我对ExtractFilePathExtractFileDir 有点困惑,我想知道当_system() 获得一个包含NUL 字符的UTF8 字符串时会发生什么(由于PAnsiChar 无法工作)。为什么 POSIX 规范在 UTF8 可以包含 NUL 的情况下允许 UTF8?
  • UTF-8 不编码任何零字节字符,nul 除外。我认为您对那里的某些事情感到困惑。您必须删除对CoInitializeEx 的调用。它不仅泄漏无法调用CoUninitialize,而且像这样的函数不能负责初始化COM。调用者必须控制它。 Info := Default(TShellExecuteInfo) 是当今默认初始化的方式。 ExtractFileDirExtractFilePath 都可以。包括SEE_MASK_NOCLOSEPROCESS 意味着您泄漏了进程句柄。删除该标志。
  • 谢谢!我确实了解所有问题并修复了它们。
  • 你能再给我看一个pastebin,这样我可以再检查一次。
  • 是的,这对我来说很可靠。关于Default,如果您必须支持没有Default 的版本,那么不值得尝试将其硬塞进去。如果您对记录进行零初始化,则不需要进一步的零初始化。考虑到这一点,我会这样做,更简单一点:pastebin.com/CDBGLt0Z 您可能还想知道在 Windows 版本中不传递 open 动词并让系统选择默认动词。
【解决方案2】:

你必须像这样添加open动词

_System(PAnsiChar('open ' + Filename));

【讨论】:

  • 在我看来这不是一个好方法。我认为我们现在不应该鼓励使用system -1
  • @DavidHeffernan,我只是在回答这个问题。我看不出在 Cocoa 方法上使用 Posix 函数有任何问题,这取决于您的需求。
  • system的问题已经讨论过很多次了。官方文档中有介绍。一方面,您的代码无法处理 Unicode 并不理想。你认为_System 比可可替代品更可取吗?
  • @DavidHeffernan,我不推荐 Posix 而不是 Cocoa,只推荐 answering the question 为什么代码不起作用,也不是我的代码的 inability 不处理 unicode ,这是系统方法的限制。
  • 好的。我只是认为,仅仅从表面上回答这个问题就错过了一个机会。就目前而言,除非有人像我一样大声疾呼,否则未来的访问者很可能会认为_System 是要走的路。这里的所有投票都有助于强化这一点。从表面上看,这里的投票让 Cocoa 版本看起来是个坏主意。也许是的。也许我完全错了。哦,好吧。
猜你喜欢
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 2016-06-15
  • 2011-08-16
相关资源
最近更新 更多