可以弹出来确定是否安装了某些应用程序?

时间:2019-01-01 18:16:17

标签: c++

我想为我的C ++程序找到安装了.pdf浏览器的软件。我希望使用popen,但是即使这段代码也会导致返回nun-NULL

FILE *fp;
fp = popen("abracadabraxx ", "r");

如果没有安装该应用程序,我希望无法进行分叉。我会误会什么吗?

2 个答案:

答案 0 :(得分:6)

popen打开管道。并且:

  

如果fork(2)或pipe(2)调用失败,或者该函数无法分配内存,则返回NULL。

这两个条件均与打开管道的过程无关。它们是关于管道本身的。

要确定进程是否成功,您需要进入pclose阶段,并且:

  

pclose():成功后,返回命令的退出状态;如果wait4(2)返回错误,或检测到其他错误,则返回-1。

您正在尝试捕获the event that the shell returns an exit code of 127,可以通过WEXITSTATUS获取。

示例:

#include <cstdio>
#include <iostream>
#include <sys/wait.h>

int main()
{
    FILE* fd = popen("nonexistingfoobar", "r");
    const int res = pclose(fd);
    printf("%d\n", WEXITSTATUS(res));
}

live demo

始终阅读the documentation

答案 1 :(得分:1)

  

如果没有安装该应用程序,我希望无法进行分叉

As per documentationpopen启动外壳程序(在POSIX系统上使用/bin/sh -c),并返回连接到外壳程序输出(或输入,取决于第二个参数)的文件描述符。该命令的有效性与popen“本身”的成功与否无关,因此您不会在输出中获得NULL(这是较低级别的失败(例如不可能)的预期结果)派生,创建文件描述符或exec shell本身,除非在资源匮乏的情况下,否则所有“不应该发生的事情”。

您将只获得标准外壳程序输出的shell会发出的任何消息(可能不会,因为它将出现在标准错误中);顺便说一句,这就是为什么popen通常不是一个好主意的原因之一,如果您需要对出问题的地方进行适当的诊断。

您可以 做的是检查pclose的返回码,该返回码将为您提供 shell 退出码,您可以使用该退出码找出发生问题的详细信息(如果有)。


话虽如此,通常最好将根据用户首选项“启动”文件委托给操作系统或操作系统提供的实用程序。简便的方法是Windows上的ShellExecute API,macOS上的open实用程序和大多数 Linux安装中的xdg-open实用程序 1 < / sup>。

对于获取用于启动文件的可执行文件,这是一种更为复杂的方法。我不知道macOS,但在Windows上,文件可能与比“普通”可执行文件(可能是通过命令行)更复杂的东西相关联-曾经有DDE命令,一些自动安装的新MSI讨厌按需填充和其他“魔术”外壳填充;我怀疑即使在Linux上,也会对DBus激活应用程序之类的东西提供一些中断的支持;因此,通常没有“关联可执行文件”之类的东西,只需要求系统打开文件并避免这种麻烦即可。


  1. 与往常一样,Linux“桌面”内容比所需的更加分散,复杂和不可靠,但是xdg-open通常是一个安全的赌注(尽管我也看到它失败了)。不要沿着Firefox自己尝试做这些事情的道路前进,否则您也会因启动错误的应用程序而存在10年的错误,并会定期出现。
相关问题