【发布时间】:2016-05-08 16:35:10
【问题描述】:
我正在尝试使用 TProcess 启动 TextEdit,并为其提供一个刚刚由调用程序编写并关闭的文本文件,该调用程序是终端上调用的命令行程序。
我第一次运行它时(见下面的摘录),它可以工作。这种情况是在计算机重新启动后尚未使用 TextEdit 的情况。
在那之后的每一次后续试验中,在之前使用过 TextEdit 之后,TextEdit 都会重新显示一条模态错误消息:
"The document “DocName.PRN” could not be opened. You don’t have permission."
但是使用 GetInfo 我发现权限完全正常,并且使用 TextEdit '手动'打开文件并不困难。
因为 TextEdit 会启动并找到文档,所以我怀疑启动本身有什么问题。我确实尝试过同步启动,但这并没有改变 TextEdit 的权限消息,但确实需要我强制退出 TextEdit,之后调用程序将挂起(无法终止但什么也不做)。
有人知道这里发生了什么,以及如何解决它吗?
...
procedure launch (prm :array of string; syn :LaunchSyncType);
var
X :integer;
Proc: TProcess;
begin
Proc := TProcess.Create(nil);
with Proc do begin
try
Executable:= prm[0]; {exe;}
for X := 1 to high(prm) do
Parameters.Add(prm[X]);
InheritHandles := False;
for X := 1 to GetEnvironmentVariableCount do
Environment.Add(GetEnvironmentString(X));
ShowWindow := swoShow; {used by Windows only}
if syn = Synchronous then
Options := Options + [poWaitOnExit]
else begin {asynchronous}
Options := [];
end;
Execute;
finally
Free;
end;
end;
end;
...
launch( ['/Applications/TextEdit.app/Contents/MacOS/TextEdit',
'/Users/lor/LorDev/LOR/DocName.PRN'],
Asynchronous );
【问题讨论】:
-
我不完全确定我是否遵循了用例,但问题可能是由于沙盒。当沙盒进程创建子进程时,子进程会继承沙盒,但不会继承 PowerBox(打开的对话框)添加的任何临时权限。
-
@Ken 这是一个有趣的建议。我已经使用相同的方法(如上)几次调用其他程序、Adobe 的 PDF 阅读器、打开命令以及我编写的几个程序,但没有一个有任何类似的问题。不过,我会尝试将 InheritHandles 设置为 true,看看会发生什么。
-
@Ken Setting
InheritHandles := True没有任何帮助。我现在通过启动/usr/bin/open而不是TextEdit 来解决这个问题,但这只是因为我的文档名称后缀是.PRN,它是使用TextEdit 作为默认打开处理程序设置的。它不会帮助任何没有适当的默认打开器的文档名称后缀。 -
首先,
/usr/bin/open只使用启动服务 API。您可以而且应该直接使用该 API,而不是调用/usr/bin/open。其次,无论您使用 Launch Services 还是/usr/bin/open,您都可以强制将文档发送到应用程序,即使该应用程序未声明它接受该文档类型。最后,我怀疑InheritHandles与我对沙盒的建议有什么关系。您的子进程根本不允许访问该文件(通过路径),因为它已被沙盒化,并且没有以一种受支持的方式授予对它的访问权限。 -
@Ken,Xcode 支持的 Swift 或 Objective-C 可以使用 Launch Services API,但是这个程序是用 Free Pascal 编写的,因为它(声称的)跨平台兼容性。 Free Pascal 提供了 TProcess 类,如我的问题所示。为此,可以付出更多努力,在自定义类中实现指向 Apple API 的链接。 Pascal TProcess 类应该提供接口,但它是 TextEdit 的一个功能,它阻止了成功。请注意它在重新启动后第一次是如何工作的,但此后就不行了。因此,沙盒问题是禁忌的。
标签: macos terminal permissions freepascal textedit