我已经使用两个可执行文件实现了类似的功能,一个用于另一个的GUI前端,使用管道、套接字、共享内存或Applescript(等等)进行通信。这个问题是是否可以使用单个可执行文件和单个应用程序进程空间来完成这个操作。
有没有一种方法可以在不向命令行可执行文件传递新的命令行参数的情况下完成此操作?(因为与命令行应用程序的使用相关的遗留问题)。
Info.plist
的LSEnvironment
键的文档中,指定的环境变量只有在通过Finder启动应用程序时才会定义。LSEnvironment
中定义一个变量(我们称之为MYAPP_GUI
),并在启动时检查它的值,那么在使用Finder时它应该存在,而在使用Terminal时则不存在。这将告诉您是否显示GUI或使用stdio。int main(int argc, const char * argv[]) {
int status = -1;
@autoreleasepool {
do {
NSProcessInfo *procInfo = [NSProcessInfo processInfo];
// deterine "UI" launch versus "command-line
id uiEnvVar = [[procInfo environment] objectForKey:@"LaunchUI"];
if([uiEnvVar isKindOfClass:[NSString class]] && [uiEnvVar isEqualToString:@"Yup"] ) {
status = NSApplicationMain(argc, argv); //launch app normally with UI
break;
}
id arguments = [procInfo arguments];
if (arguments == nil) {
printUsage();
break;
}
if ([arguments count] == 1 || [arguments containsObject:@"-h"] || [arguments containsObject:@"-help"]) {
printUsage();
status = 0;
break;
}
//process further arguments
if(processArgs(arguments) == NO) {
printUsage();
break;
}
// kick off protection.
if(YES != do_work()) {
break;
}
status = 0; //
// if your command-line should stay alive and handle events - you can do the following to block it from exiting.
[[NSRunLoop currentRunLoop] run];
} while(false);
}
return status;
}
我认为这差不多就是了。享受吧!
是的,只需在程序中添加一个开关--command-line
。除非在运行时传递了--command-line
参数,否则启动正常的GUI。
./myprog --command-line
这基本上就是全部内容了。
--command-line
开关一样的东西。 - Corey Ogburnmain()
函数的一些示例代码。 - ZnArK需要注意的是,这是我在 .Net 应用程序中所做的事情,我认为这个想法可以在其他语言和平台上实现。
我会创建一个控制台应用程序,然后仍然使用所有 GUI 类。当程序启动时,根据确定它是 GUI 实例还是命令行实例的任何标准,我要么启动 GUI,要么相应地启动命令行界面。
最重要的是,您必须有一些条件来确定何时要显示 GUI 而不是命令行。也许通过关于会话的系统变量(它是否是 ssh 会话,然后是命令行,否则是 GUI)。
我认为以你期望的方式是不可能的。GUI OSX 应用实际上是应用程序包,即它们实际上是包含除了实际可执行文件之外的大量资源的目录。你肯定不能像命令行可执行文件一样在 shell 中执行这些包(例如,你不能在 shell 提示符上执行 ./MyApplication.app --some-option
,因为你的 shell 不知道如何执行目录),尽管你可能知道你可以通过 open MyApplication.app
以 GUI 方式运行它们。现在,你可以访问包内的实际可执行文件,并且可能有可能使该可执行文件作为 CLI 可执行文件工作——我在这里胡说八道,因为我没有使用 Xcode 工具及其构建系统的实际经验,但可能有可能使实际可执行文件在 CLI 和 GUI 调用中都能工作。
然而,这并不是非常有用,因为这些可执行文件被埋藏在应用程序包中,通常无法直接在 shell 中调用(即它们肯定不在您的 $PATH 中,因此您必须将它们作为类似 ./MyApplication.app/Contents/MacOS/actualbinaryname
的东西来调用)。我在现实世界中看到的通常方法是提供一个单独的 CLI 可执行文件和您的应用程序捆绑在一起,这通常会通过安装程序或通过单击应用程序首选项中的按钮放置在适当的位置(例如 /usr/local/bin)。如果您打算与 GUI 应用程序交互,那么这些 CLI 可执行文件会负责处理它(从您的问题中并不清楚您是否是这样做)。
如果我理解有误请见谅,但是如果你正在使用Objective-C,那么其中一部分答案不是使用Objective-C中的NSProcessInfo类并检查“arguments”变量以确定是否传递了任何参数,然后在代码中决定下一步该做什么吗?