osx:如果父 运行 打开,外部程序 (qprocess) 崩溃,但如果父 运行 直接打开,则工作正常

osx: external program (qprocess) crash if parent run with open, but works fine if parent run directly

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

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

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

但是一旦我使用"open myApp.app"或通过UI启动它,然后QProcess exitCode() returns 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;

任何帮助将不胜感激。

I have 32-bit Qt application packed in a bundle.

首先,以防万一你错过了这个,Apple 已经声明 OS (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 启动了不同的应用程序,而不是您认为正在执行的应用程序。确保您的计算机上没有该应用程序的其他副本。

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

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

对于将面临同样情况的人: 在 macOS 中,bundle 应用程序具有与 bundle 相关的工作目录,但与 Windows.

中发生的执行文件本身无关

所以在我的例子中,下一个代码有效:

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