通过NSTask发行X11应用程序的问题 [英] Issue launching X11 app via NSTask

查看:96
本文介绍了通过NSTask发行X11应用程序的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序使用NSTask执行Shell脚本,其中一个脚本启动了X11应用程序(特别是meld).

My app uses NSTask to execute shell scripts, one of those scripts launches an X11 app (specifically meld).

我希望它能起作用:

#!/bin/bash
source ~/.profile                      # setup $PATH/etc
meld .

但是它失败了:

gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
Traceback (most recent call last):
  File "/usr/local/bin/meld", line 132, in <module>
    gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
AttributeError: 'NoneType' object has no attribute 'append_search_path'

作为概念证明,我将脚本更改为此脚本,效果很好:

As a proof of concept I changed the script to this, which works perfectly:

#!/usr/bin/ruby

exec 'osascript -e \'tell app "Terminal" to do script "meld ' + Dir.pwd + '" in front window\''

有人引起问题吗?这是我执行Shell脚本的代码:

Does anyone what is causing the problem? Here is my code for executing the shell script:

NSTask *task = [[NSTask alloc] init];
task.launchPath = self.scriptURL.path;
task.standardOutput = [NSPipe pipe];
task.currentDirectoryPath = workingDirectoryURL.path;

[task launch];

推荐答案

X11应用程序使用DISPLAY环境变量来学习显示服务器的地址.

X11 apps learn the display server's address using the DISPLAY environment variable.

在OS X上,出于安全原因,DISPLAY值是随机的,因此您无法像注意到的那样对其进行硬编码.取而代之的是,有一个启动的代理程序告诉启动器在启动进程时设置DISPLAY.

On OS X, the DISPLAY value is randomized for security reasons, so you can't hard-code it, as you noticed. Instead, there is a launchd agent that tells launchd to set DISPLAY when it starts a process.

在启动和合并之间的某个位置,DISPLAY的值被删除或覆盖.您的工作就是找出位置.

Somewhere between launchd and meld, the value of DISPLAY is being dropped or overwritten. Your job is to find out where.

  1. 确保启动的代理正在运行.运行launchctl list并查找org.macosforge.xquartz.startx.由于meld正在Terminal.app中运行,因此这部分可能是正确的.
  2. 确保在您的应用中设置了显示".它应该在[NSProcessInfo processInfo].environment中列出.
  3. 确保在启动的NSTask中设置了DISPLAY.尝试使用NSTask运行/usr/bin/env,并确保DISPLAY出现在其输出中.
  4. 确保在运行的脚本中设置了DISPLAY.在采购〜/.profile之前和之后尝试echo $DISPLAY. (有时,.profile本身会将DISPLAY覆盖为不正确的值,因为在其他操作系统上有时这样做是正确的.)
  1. Make sure the launchd agent is running. Run launchctl list and look for org.macosforge.xquartz.startx. Since meld is working from Terminal.app this part is probably correct.
  2. Make sure DISPLAY is set in your app. It should be listed in [NSProcessInfo processInfo].environment.
  3. Make sure DISPLAY is set in the NSTask you launch. Try running /usr/bin/env with an NSTask, and make sure DISPLAY appears in its output.
  4. Make sure DISPLAY is set inside the script you run. Try echo $DISPLAY before and after sourcing ~/.profile. (Sometimes the .profile itself overwrites DISPLAY to an incorrect value because that's sometimes the right thing to do on other operating systems.)

编辑:这是我用来将DISPLAY从我的GUI应用复制到shell脚本的代码:

this is the code I used to copy DISPLAY from my GUI app to the shell script:

NSTask *task = ...
task.environment = [NSProcessInfo processInfo].environment;
[task.launch];

这篇关于通过NSTask发行X11应用程序的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆