【问题标题】:Is it possible to set an NSTask-owned window front and key?是否可以设置 NSTask 拥有的窗口前端和键?
【发布时间】:2012-01-26 22:36:41
【问题描述】:

我正在开发一个 Mac 应用程序,该应用程序可以选择提供安装一些苹果包格式的额外软件的能力。这个包需要提升(root)权限才能安装,而不是使用帮助工具或AuthorizationExecuteWithPrivileges(),我认为使用 NSTask 调用/usr/bin/open 甚至/System/Library/CoreServices/Installer.app/Contents/MacOS/Installer 与包的路径和让它处理用户授权。

所以,它工作得很好,很漂亮,但是安装程序窗口没有出现在堆栈的前面,也不是关键。我可以在启动任务之前orderOut 调用窗口,这有助于排序,但关键真的是,好吧,让它成为关键。

我是否应该继续实施 Apple 的 BetterAuthorizationSample,因为我可能不得不在将来的某个时候使用它,并且因为尝试过它会成为一个更好的人?

【问题讨论】:

  • 一定要使用 Apple 安装程序。编写自己的安装程序并不像您想象的那么简单。另外,如果可能的话,尽量避免使用命令行工具,通常有一个 API 可以做你想做的事。 open 命令行工具基本上是 Launch Services C API 的包装器。您可以直接或通过 NSWorkspace 访问该 API,这是一个包含多个启动服务调用的 Objective-C API。
  • 哦,是的,我肯定会使用苹果的安装程序!是Installer.app 还是installer,尚未确定。

标签: objective-c cocoa nstask


【解决方案1】:

有两个变量决定哪个窗口是关键。其中之一是应用程序中的设置,它确定哪个窗口处于焦点,另一个是哪个应用程序处于活动状态。在我们自己的应用程序中隐藏窗口将使安装程序可见,但除非您使安装程序应用程序处于活动状态,否则它不会成为关键。您有几种选择。

首先,您可以使用以下方法停用您的应用程序:

[[NSApplication sharedApplication] deactivate];

接下来,您可以找到安装程序的NSRunningApplication 并激活它:

NSArray *apps = [[NSWorkspace sharedWorkspace] runningApplications];
NSRunningApplication *app = // find installer
[app activateWithOptions:0];

但在您的情况下,我建议使用NSWorkspace 为您打开安装程序,而不是通过NSTask 启动它。 NSWorkspace 会自动停用您的应用程序,因此您不必这样做,您会收到有关文件是否打开成功的反馈,并自动选择打开它的应用程序。

BOOL success = [[NSWorkspace sharedWorkspace] openFile:@"path/to/file.pkg"];

【讨论】:

  • 太棒了,彼得。我曾简要查看过 NSWorkspace 的 openFile,但我想知道安装本身是否成功完成。似乎只有 NSTask 可以返回终止状态。我想我总是可以使用 NSWorkspace 方法查看包裹收据,但这似乎不可靠。
  • 我偶然发现并最终使用STPrivilegedTask 在后台运行安装程序。
【解决方案2】:

您可以通过在 applicationDidFinishLaunching 处理程序中包含以下代码来强制将进程置于代码中:

ProcessSerialNumber process;
GetCurrentProcess(&process);
SetFrontProcess(&process);

这将使它成为最前面的过程,而不管其他任何事情。不过,您需要链接到 Carbon。

【讨论】:

  • 这行得通,但它解决的是症状而不是根本原因。如果您使用适当的 API 启动程序,它应该首先启动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2020-01-05
  • 2013-05-10
相关资源
最近更新 更多