在C++中抑制system("ping")的输出

7
我写了一个简单的程序,它会ping三个网站,并根据它们是否可达做出反应。
我的问题是:我能否抑制system("ping")的输出?我用C++编写了代码,因为我最擅长这种语言。目前,该代码打开ping.exe运行系统命令。如果我可以防止输出显示,同时仍然进行ping操作,那就太理想了。
我最终将把此程序转换为Windows服务,因此我希望抑制命令行控制台窗口以及抑制ping输出。谢谢。

一个带有WinMain()的Win32应用程序不会阻止命令行窗口出现吗? - Mateen Ulhaq
1
我不知道如何抑制输出,但ping是一种情况,你通常要避免使用system()。 - Roger Pate
@muntoo:调用控制台程序意味着它需要一个控制台;控制台程序在Windows的PE格式中有一个特殊标志,因此它们略有不同。 - Roger Pate
我很想知道如何在不使用系统ping的情况下ping,但我对编程相当新,因此我在网上找到的东西最多只是极其令人困惑的 :( - Samuel
6个回答

21

尝试执行 system("ping host > nul")nul是Windows中UNIX /dev/null的等价物)。


2
如果我能把你标记为答案就好了...但可惜我没有问这个问题。 - Corey Ogburn
4
无需冒号,"nul"足矣。 - avakar
3
@Samuel,@zvrba:我可以放一个名为 ping.exe 的恶意可执行文件,你们的程序就会挂掉。你们几乎永远不应该使用 system():http://www.cplusplus.com/forum/articles/11153/ 如果你们正在开发一个 Windows 服务,那么情况至少要糟糕两倍。 - Lie Ryan
2
即使他的可执行文件具有仅执行权限(即无法破坏可执行文件),但如果程序的当前目录是每个人都具有写访问权限的目录(这种情况非常普遍),那么您不需要一个被攻击的系统来替换 ping.exe 为恶意程序。 - Lie Ryan
2
@zvrba:这是任何共享系统中常见的情况。如果您的低权限用户可以写入该目录,则他们可以获得您程序的特权;换句话说,如果您使用system()调用,则会将程序的特权泄漏给系统上的所有人。除非您完全信任所有用户(这在共享系统中从不发生,除非您是妄想症),否则使用system()的程序是安全隐患。 - Lie Ryan
显示剩余4条评论

6

通常情况下,如果你想调用另一个程序但不希望它像std::system一样运行,你需要使用类似于UNIX上的fork()/exec()或Windows上的CreateProcess()这样的平台特定函数。这些函数可以让你控制其他程序的运行方式,例如,不显示输出或不创建控制台窗口等。


3
您可以使用以下系统命令来抑制ping命令的输出。
system("ping 100.100.100.100 > response.dat");

上述命令会对IP地址100.100.100.100进行ping测试,并将输出结果保存到名为response.dat的文件中。你可以在response.dat文件中查看ping命令的响应结果。

谢谢bjskishore,知道如何将输出发送到文件中如果需要的话非常好。 - Samuel

2
执行system("ping site.com >nul 2>nul");并检查shell返回的值。 如果ping成功,shell将返回0,否则将返回1。 我可以提供更详细的信息,但是Vis Studio正在重新安装。 :)
还有一种使用Win API隐藏控制台窗口的方法来执行命令,但是... 我不记得细节了。
编辑: 我还在等待MSVS安装过程,所以... :) 使用DETACHED_PROCESS标志作为dwCreationFlags参数调用CreateProcess以隐藏控制台窗口。
在调用create process之后,您必须使用进程句柄上的WaitForSingleObject等待ping完成。 CreateProcess的最后一个参数应该具有包含进程句柄的进程信息的指针(假设CreateProcess成功)。 您必须等待命令完成。 完成后,您可以使用进程句柄获取返回值,但是我现在没有时间告诉您如何做到这一点。

谢谢你的回答,我很想了解更多关于隐藏控制台窗口的内容,那将会非常棒。 - Samuel

2

当你使用Windows并调用CreateProcess()时,请确保设置:

    lpStartupInfo->wShowWindow = SW_HIDE;

这将确保新进程创建的任何窗口都被隐藏。
使用DETACHED_PROCESS标志将防止新进程继承您应用程序的控制台,但这并不妨碍新进程创建新控制台。不确定ping会做什么,但最好使用SW_HIDE以消除所有疑虑。

lpStartupInfo在哪个库中? - Samuel
嗨,塞缪尔。lpStartupInfo是CreateProcess()函数的倒数第二个参数。请参考该函数的文档以获取详细信息(请参见我原始帖子中的链接)。 - CoreTech

2
您也可以使用以下方式,将输出返回到文件中,不会显示控制台窗口并冻结主应用程序,这非常有用。首先需要使用以下代码包含Windows头文件;
#include <Windows.h>

然后发送ping命令并将输出写入文件,如下所示:
WinExec("ping google.com > file.dat", SW_HIDE); 

这将发送一个ping命令到google.com,并将输出写入当前运行程序目录下的文件'file.dat'。因此,你可以更改file.dat为任何文件或文件路径,当然你也可以更改ping命令。 >字符意味着命令的输出需要被写入它后面的文件路径中。 如果你想要显示控制台窗口并在运行ping命令时冻结应用程序,你需要使用以下代码行而不是WindExec()代码:
system("ping google.com > file.dat");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接