Подавить вывод системы (ping) в C++

Я написал простую программу, которая пингует три сайта, а затем реагирует на то, доступны они или нет.

Мой вопрос: могу ли я подавить вывод системы ("ping")? Я написал свой код на C++, так как знаю этот язык лучше всего. В настоящее время код открывает ping.exe, выполняя системную команду. Если бы я мог предотвратить появление вывода, пока он все еще пингуется, это было бы идеально.

В конечном итоге я собираюсь превратить эту программу в службу Windows, поэтому я хотел бы подавить как окно консоли командной строки, так и подавить вывод ping. Спасибо.


person Samuel    schedule 31.10.2010    source источник
comment
Разве приложение Win32 (с WinMain()) не препятствует появлению командной строки?   -  person Mateen Ulhaq    schedule 31.10.2010
comment
Я не знаю о подавлении вывода, но проверка связи — это одна из тех ситуаций, когда вы обычно избегаете system().   -  person    schedule 31.10.2010
comment
@muntoo: вызов консольной программы означает, что ей нужна консоль; консольные программы имеют специальный флаг в формате Windows PE, поэтому они немного отличаются.   -  person    schedule 31.10.2010
comment
Я хотел бы знать, как пинговать без использования системного пинга, но я довольно новичок в программировании, и поэтому то, что я нашел в Интернете, было в лучшем случае чрезвычайно запутанным :(   -  person Samuel    schedule 31.10.2010


Ответы (6)


Попробуйте выполнить system("ping host > nul") (nul является Windows-эквивалентом UNIX /dev/null).

person zvrba    schedule 31.10.2010
comment
Если бы я только мог пометить вас как ответ... но, к сожалению, я не задал вопрос. - person Corey Ogburn; 31.10.2010
comment
Нет необходимости в двоеточии, вполне достаточно nul. - person avakar; 31.10.2010
comment
Спасибо, этот ответ очень краткий и удивительный. - person Samuel; 31.10.2010
comment
@Samuel,@zvrba: Я могу поставить вредоносный исполняемый файл с именем ping.exe, и ваша программа будет облажаться. Вы почти никогда не должны использовать system(): cplusplus.com/forum/articles/11153 Если вы делаете службу Windows, то ситуация как минимум в два раза хуже. - person Lie Ryan; 31.10.2010
comment
@Lie: 1) Я редко сомневаюсь в ОП. Он получил ответ на свой вопрос. 2) Если ваша система скомпрометирована, вы облажались, какой бы метод порождения вы ни использовали, и какой бы процесс вы ни порождали. Так в чем именно заключается ваша точка зрения? - person zvrba; 31.10.2010
comment
@zvrba: даже если его исполняемый файл имеет разрешение только на выполнение (т. Е. Вы не можете скомпрометировать исполняемый файл), но если текущий каталог программы является каталогом, к которому у всех есть доступ для записи (что довольно часто бывает), то вам не нужна скомпрометированная система, чтобы заменить ping.exe вредоносной программой. - person Lie Ryan; 31.10.2010
comment
@Lie: гм, значит, неизвестный исполняемый файл каким-то образом (неважно, что это значит) попадает в какой-то каталог и ожидает выполнения. Так как бы вы назвали это, если бы не скомпрометированная система? - person zvrba; 31.10.2010
comment
@zvrba: это обычный сценарий в любой общей системе. Если кто-либо из ваших пользователей с низкими привилегиями может писать в этот каталог, они могут получить привилегии вашей программы; другими словами, если вы используете вызов system(), вы передаете привилегию своей программы всем в системе. Если вы не можете полностью доверять всем своим пользователям (что никогда не бывает в системах с общим доступом, если только вы не заблуждаетесь), то ваша программа, использующая system(), представляет угрозу безопасности. - person Lie Ryan; 31.10.2010
comment
@zvrba: этот конкретный аргумент об отказе от использования system() является спорным, если программа, которую вы пишете, предназначена для выполнения самим пользователем, поскольку программы, которые вы выполняете самостоятельно, будут использовать ваши собственные привилегии (если иное не настроено системным администратором) ; но OP пишет службу Windows, что означает, что программа, скорее всего, будет иметь другой уровень привилегий, чем текущий пользователь, это реальное соображение безопасности. - person Lie Ryan; 31.10.2010

Как правило, если вы собираетесь вызывать другую программу, но не хотите, чтобы она действовала как std::system, вам понадобится функция для конкретной платформы, такая как fork()/exec() в UNIX или CreateProcess() в Windows. Эти функции дают вам контроль над тем, как работает другая программа, например, чтобы она не отображала вывод или не создавала окно консоли и т. д.

person Max Lybbert    schedule 31.10.2010

Вы можете использовать системную команду, как показано ниже, чтобы подавить вывод команды ping.

system("ping 100.100.100.100 > response.dat");

Приведенная выше команда пингует IP-адрес 100.100.100.100 и направляет вывод в файл с именем response.dat. В response.dat вы можете увидеть ответ команды ping.

person bjskishore123    schedule 31.10.2010
comment
Спасибо, bjskishore, очень хорошо знать, как я могу отправить вывод в файл, если это необходимо. - person Samuel; 31.10.2010

Do system("ping site.com >nul 2>nul"); и проверьте значение, которое возвращает оболочка. если ping пройдет успешно, оболочка вернет 0, иначе вернет 1. Я бы поподробнее, но Vis Studio переустанавливает себя. :)

Также есть способ скрыть окно консоли с помощью Win API для выполнения команды, но... подробностей не помню.

Изменить: я все еще жду процесса установки MSVS, так что... :) Используйте CreateProcess с флагом DETACHED_PROCESS для параметра dwCreationFlags, чтобы скрыть окно консоли.

После того, как вы вызовете процесс создания, вам нужно будет использовать WaitForSingleObject в дескрипторе процесса, чтобы дождаться завершения проверки связи. Последний параметр CreateProcess должен иметь указатель на информацию о процессе, содержащую дескриптор процесса. (Предполагая, что CreateProcess был успешным) Вам нужно дождаться завершения команды. После завершения вы можете использовать дескриптор процесса для получения возвращаемого значения, хотя у меня слишком мало времени, чтобы рассказать вам, как это сделать на данный момент.

person JimR    schedule 31.10.2010
comment
Спасибо за ответ, мне бы хотелось больше скрыть окно консоли, это было бы здорово. - person Samuel; 31.10.2010

Когда вы переходите к Windows и вызываете CreateProcess() обязательно установите:

    lpStartupInfo->wShowWindow = SW_HIDE;

Это гарантирует, что любые окна, созданные новым процессом, будут скрыты.

Использование флага DETACHED_PROCESS не позволит новому процессу наследовать консоль вашего приложения, но это не помешает новому процессу создать новую консоль. Не уверен, что сделает ping, но лучше всего развеять все сомнения с помощью SW_HIDE.

person CoreTech    schedule 31.10.2010
comment
В какой библиотеке находится lpStartupInfo? - person Samuel; 02.11.2010
comment
Привет Самуэль. lpStartupInfo — предпоследний параметр функции CreateProcess(). Подробную информацию см. в документации к функции (см. ссылку в моем исходном посте). - person CoreTech; 04.11.2010

Вы также можете использовать этот способ, это вернет вывод в файл, не покажет окна консоли и заморозит основное приложение, что действительно полезно. Сначала вам нужно включить заголовок 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");
person Tim Visée    schedule 13.03.2012