【问题标题】:osx: external program (qprocess) crash if parent run with open, but works fine if parent run directlyosx:如果父级以打开方式运行,则外部程序(qprocess)崩溃,但如果父级直接运行,则工作正常
【发布时间】:2018-03-22 19:07:48
【问题描述】:

我在 MacOS 10.13 上遇到了奇怪的情况,找不到它的根源。

我有一个捆绑包中的 32 位 Qt 应用程序。由于 MacOS 对其中一项操作的限制,我需要启动一个小的 64 位控制台二进制文件。这个控制台二进制文件放在 Contents/MacOS 中,我使用 QProcess 启动它。

如果我从 IDE 运行主应用程序,一切正常。另外,如果我打开终端,cd 到 Contents/MacOS 并直接运行主应用程序,一切都很好。

但是一旦我使用“open myApp.app”或通过 UI 启动它,QProcess exitCode() 就会返回 255,这似乎意味着崩溃。

子进程启动代码:

QProcess p;
p.start("./papply", QStringList() << osid << filepath);
p.waitForFinished(5000);
qDebug() << p.readAllStandardOutput();
qDebug() << p.readAllStandardError();
qDebug() << p.state();
if(p.state()==QProcess::Running)
{
  qDebug() << "peapply freezed - kill";
  p.kill();
  return false;
}

qDebug() << "Apply" << osid << filepath << "=" << p.exitCode();
return p.exitCode()==0;

任何帮助将不胜感激。

【问题讨论】:

  • 如果您更改为使用 absolute 路径到要执行的程序怎么办?如果您从 UI 运行,则“当前工作目录”很可能不正确。
  • @Someprogrammerdude 谢谢,我现在试试
  • @Someprogrammerdude 绝对路径有帮助。请将其作为要选择的答案。

标签: c++ macos qt qprocess


【解决方案1】:

我有一个打包成一个包的 32 位 Qt 应用程序。

首先,万一您错过了这一点,Apple 已声明下一个版本的操作系统 (10.14) 将不支持 32 位应用程序,因此如果您想在其上运行此应用程序,则需要更改此设置macOS 的未来版本。

如果您使用调试器,或从包的Contents/MacOS 文件夹运行二进制文件,它会直接执行。相反,如果您双击二进制文件,或在终端使用open 关键字,则会向Launch Services 发送请求,以代表您打开应用程序。

Launch Services (LS) 维护与应用程序 Bundle Identifier 的关联,该应用程序位于应用程序包的 Info.plist 文件中。

当使用 LS 打开应用程序的请求发生时,LS 会显示来自应用程序 plist 的 Bundle Identifier,并且 LS 将使用该标识符执行已为 registered 的应用程序。

在 plist 中,我们还有键 CFBundleExecutable,它被定义为“(推荐)捆绑包的可执行文件的名称”。这是可能执行的二进制文件的名称,位于 Contents/MacOS 文件夹中。

注意,由于 LS 启动与给定标识符关联的应用程序,如果您的机器上有相同应用程序的副本,具有相同的版本号和标识符,它可能不一定执行您双击的应用程序,运行。

因此,崩溃的原因很可能是由于 LS 启动了不同的应用程序,而不是您认为正在执行的应用程序。确保您的计算机上没有应用程序的其他副本。

如果生成了崩溃报告,您应该能够在图像部分的开头看到应用程序的路径,其中包括动态库和框架的路径。

【讨论】:

  • 谢谢。这不是我的情况,因为我只有一个正确安装的应用程序实例。但无论如何,您的信息非常有趣且很有帮助。
【解决方案2】:

虽然@TheDarkKnight 提供了很好的信息,但并不完全是答案。

对于将面临同样情况的人: 在 macOS 中,捆绑应用程序具有与捆绑相关的工作目录,但与在 Windows 中发生的执行文件本身无关。

所以在我的情况下,下一个代码有效:

QString path = qApp->applicationDirPath();
if(!path.endsWith("/"))
    path += "/";
QProcess p;
p.start(path + "papply", QStringList() << osid << filepath);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2013-01-30
    相关资源
    最近更新 更多