通过NSTask发行X11应用程序的问题 [英] Issue launching X11 app via NSTask
问题描述
我的应用程序使用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.
- 确保启动的代理正在运行.运行
launchctl list
并查找org.macosforge.xquartz.startx.由于meld
正在Terminal.app中运行,因此这部分可能是正确的. - 确保在您的应用中设置了显示".它应该在
[NSProcessInfo processInfo].environment
中列出. - 确保在启动的NSTask中设置了DISPLAY.尝试使用NSTask运行
/usr/bin/env
,并确保DISPLAY出现在其输出中. - 确保在运行的脚本中设置了DISPLAY.在采购〜/.profile之前和之后尝试
echo $DISPLAY
. (有时,.profile本身会将DISPLAY覆盖为不正确的值,因为在其他操作系统上有时这样做是正确的.)
- Make sure the launchd agent is running. Run
launchctl list
and look for org.macosforge.xquartz.startx. Sincemeld
is working from Terminal.app this part is probably correct. - Make sure DISPLAY is set in your app. It should be listed in
[NSProcessInfo processInfo].environment
. - 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. - 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屋!