POPEN 可以找出是否安装了某些应用程序吗?

can popen find out if some application is installed?

本文关键字:应用程序 安装 是否 POPEN      更新时间:2023-10-16

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

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

我预计如果未安装该应用程序,则无法分叉。我是不是误会了什么?

popen打开一个管道。和:

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

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

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

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

您正在尝试捕获 shell 返回退出代码 127 的事件,您可以通过WEXITSTATUS获取该代码。

例:

#include <cstdio>
#include <iostream>
#include <sys/wait.h>
int main()
{
FILE* fd = popen("nonexistingfoobar", "r");
const int res = pclose(fd);
printf("%dn", WEXITSTATUS(res));
}

(现场演示)

请务必阅读文档!

我预计如果未安装应用程序就无法分叉

根据文档,popen启动 shell(在 POSIX 系统上使用/bin/sh -c),并返回连接到 shell 输出(或输入,取决于第二个参数)的文件描述符。命令的有效性与popen"本身"的成功无关,因此您不会在输出中得到NULL(这对于较低级别的故障是可以预期的,例如无法分叉,创建文件描述符或execshell本身,除非在资源不足的情况下,否则所有"不应该发生"的事情)。

你只会得到 shell 在标准输出上吐出的任何消息(可能没有,因为它会在标准错误上);顺便说一下,这就是为什么如果你需要对错误进行体面的诊断,通常popen不是一个好主意的原因之一。

但是,您可以做的是检查pclose的返回代码,它将为您提供shell退出代码,您可以使用该代码来查找有关出错情况(如果有)的一些详细信息。


话虽如此,根据用户偏好"启动"文件通常最好委托给操作系统或操作系统提供的实用程序;简单的方法是 Windows 上的ShellExecuteAPI、macOS 上的open实用程序和大多数Linux 安装上的xdg-open实用程序1

至于让可执行文件用于启动文件,这是一个更复杂的问题。我不了解 macOS,但在 Windows 上,文件可能与比"普通"可执行文件(可能带有命令行)更复杂的东西相关联 - 曾经有 DDE 命令,一些新的花哨的 MSI 可憎之物,可以按需自动安装东西和其他"神奇"的外壳东西;我怀疑即使在 Linux 上,对应用程序的 DBus 激活和类似的东西也会有一些破碎的支持;因此,一般来说,没有"关联的可执行文件"这样的东西,只需要求系统打开文件并远离这种麻烦即可。


  1. 与往常一样,Linux的"桌面"内容比它需要的更加分散,复杂和不可靠,但xdg-open通常是一个安全的赌注(尽管我也看到它失败了)。不要沿着 Firefox 尝试自己做这些事情的道路走下去,否则你也会在错误的应用程序上出现 10 年前的错误错误,这些错误会定期重新出现。
相关文章: