【问题标题】:Using popen() to open a program in command line?使用 popen() 在命令行中打开程序?
【发布时间】:2011-08-30 15:24:24
【问题描述】:

是否可以使用另一个程序打开一个程序?例如: 我想在 C 中创建一个命令行应用程序,它会提示用户输入程序的名称(比如说 Microsoft Word.app),然后该程序将启动。我会做这样的事情吗:

#include <stdio.h>
#include <time.h>
int main (int argc, const char * argv[]) {
    char programName[1000];
    printf("Type in the name of the program you would like to open: ");
    scanf("%s", programName);
    popen(programName);
}

但是,popen() 要求我输入另一个字符。我将如何使用 popen() 打开程序?

编辑:以下代码有效!

#include <stdio.h>
#include <time.h>

int main (int argc, const char * argv[]) {
    char programName[1000];
    char app[100] = ".app";
    char openApp[100] = "open /Applications/";
    printf("Type in the name of the program you would like to open: ");
    scanf("%s", programName);
    strcat(openApp, programName);
    strcat(openApp, app);
    system(openApp);

}

【问题讨论】:

  • 尽管您的以下代码有效,但它有可能因在 strcat 中的缓冲区上运行而崩溃,您正在将可能 1000 个字符的数组添加到最多只能容纳 100 个字符的目标中。字符打开应用程序[100];必须至少为 char openApp[100 + 1000 + 20];

标签: c xcode command-line popen


【解决方案1】:

popen 允许您启动程序并获取其输入或输出的文件描述符,就像fopen 用于文件一样。例如,如果您想读取程序的输出,您可以使用popen("program", "r")。另一方面,如果你想写入它的输入,你会使用popen("program", "w")。 Mac OS X 还允许r+,它允许您读取输出并写入输入,但此功能不是标准的,不应依赖于跨平台代码。

如果您只想启动一个程序,您不妨使用system 函数,它会执行此操作并等待程序退出,此时它会返回状态码。 system 实际上是调用 shell 来工作,所以参数会进行扩展(环境变量、~ 等)。

编辑根据您的评论,system("Microsoft Word.app") 没有按您的预期工作:实际上有几个原因。从你得到的消息开始:这是因为你写的内容相当于打开一个终端窗口并输入Microsoft Word.app。换句话说,它试图找到一个名为“Microsoft”的程序,然后将参数“Word.app”传递给它。您需要引用程序名称或转义空格以让 shell 理解它是一个完整的程序名称而不是程序名称,然后是一个参数:system("Microsoft\ Word.app")

现在,这应该会抱怨说 shell 找不到程序“Microsoft Word.app”,这已经是向前迈出了一步。

这是因为在 Mac OS 上,app 文件不是可执行文件:它们是 Finder 显示为单个文件的文件夹。您可以通过 ctrl+单击(或右键单击)应用程序并选择“显示包内容”(这将打开应用程序文件夹)来验证这一点。 Microsoft Word.app 的实际可执行文件必须位于 Microsoft Word.app/Contents/MacOS/Microsoft Word 路径上的某个位置。

如您所见,这变得有点复杂。幸运的是,Apple 提供了open 可执行文件,它可以使用一系列操作系统服务来找出这些细节。它允许以下列方式启动应用程序:

open -a Microsoft\ Word

这应该会启动 Word。 (请注意您仍然需要如何转义空格。)在纯 C 代码中,您会得到这样的结果:

system("open -a Microsoft\\ Word");

但是,如果您选择使用 Objective-C 和 Cocoa,有一种非常简单的方法可以打开应用程序:

NSString* appName = @"Microsoft Word"; // no escape!
[[NSWorkspace sharedWorkspace] launchApplication:appName];

NSString 对象可以很容易地从 C 字符串创建:

NSString* appName = [[NSString alloc] initWithCString:programName encoding:NSUTF8StringEncoding];
[[NSWorkspace sharedWorkspace] launchApplication:appName];
[appName release];

【讨论】:

  • @zneak 当我这样做时,它说找不到命令。我假设我做错了什么。输入您要打开的程序的名称:正在运行... Microsoft Word.app sh: Microsoft: command not found
  • 那么如果应用程序只有一个单词,我不需要转义空格?
  • @Mike,没错。但是,如果您不验证此输入,则应确保您的用户未输入可能有害的程序名称。如果您愿意进入 Objective-C 并使用 Cocoa 框架,您可以轻松启动具有“复杂”名称的程序(我已经编辑了我的答案以反映这一点)。
  • 谢谢!我得试着为这个应用程序做一个界面。
  • @Mike,您也可以将 Cocoa 用于命令行程序。您需要将 Cocoa 框架添加到您的项目中,并将文件的扩展名更改为 .m 而不是 .c
【解决方案2】:

最好使用system(3) 来达到这个目的。

popen(3) 函数建立了一个可由调用者读取或写入的管道。但是 GUI 应用程序不使用标准输入和标准输出,它们连接到图形界面服务器,有时称为 "window server". 该服务器已经在运行并且已经决定了它的键盘输入是什么,并且它总是将其输出写入视频设备。

要启动 .app,您应该实际运行 open(1) 程序,因此请尝试以下操作:

system("open /Applications/MacVim.app");

【讨论】:

  • 这最终会在 finder 中打开应用程序位置
猜你喜欢
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 2017-07-11
  • 2014-11-15
  • 1970-01-01
相关资源
最近更新 更多