QProcess
- одновременно мощный и удобный модуль библиотеки Qt для запуска и управления процессами. Нельзя забывать, что он еще и весьма опасен. Однако здесь мы не будем затрагивать вопросы информационной безопасности, а лишь ограничимся базовыми приемами использования QProcess
.
Допустим, вы хотите, чтобы ваше приложение могло вызывать другую программу в виде независимого процесса. Сделать это очень легко:
Заказать кровлю высокого качества в Симферополе от производителя. Большой выбор металлочерепицы, профнастила, гибкой черепицы. Сотовый поликарбонат. Доборные элементы. Водосточная система. Адвокат по наркотикам читать дальше.
void runTest() {
static const QString PROGRAM_NAME = "notepad"; // Для примера - Блокнот
QProcess::startDetached( PROGRAM_NAME );
}
В приведенном примере осуществляется запуск приложения PROGRAM_NAME
, которое начнет существовать само по себе. Даже после завершения вашей программы с этим кодом процесс продолжит свою работу совершенно независимо.
Обратите внимание, что startDetached()
- статическая функция-член класса QProcess
. При этом она может принимать еще несколько параметров: список аргументов в виде QStringList
; рабочую директорию; и указатель на int
, в котором возвращает идентификатор нового процесса.
Это решение является довольно распространенным в мире Linux, где большинство утилит изначально выходят в форме консольных приложений. Однако не всем пользователям это нравится. По этой причине и появляются надстройки с графическим интерфейсом, которые являются посредниками между пользователями и исходной консольной утилитой. Например, QtCreator и многие другие IDE для интеграции компиляторов и систем контроля версий используют именно этот прием.
В большинстве случаев вам достаточно передать нужные аргументы на вход приложению и дождаться от него ответа:
void readTest() {
QProcess process;
process.start( "lsusb", QStringList() << "-t" );
if( !process.waitForStarted() || !process.waitForFinished() ) {
return;
}
qDebug() << process.readAllStandardError();
qDebug() << process.readAllStandardOutput();
}
В приведенном примере мы запускаем lsusb -t
(утилита для Linux). Поскольку результат выводится мгновенно, мы ждем завершения процесса с помощью waitForFinished()
и выводим то, что приложение отправило в стандартные потоки вывода stderr
и stdout
. Если же приложение выводит результаты не сразу, а постепенно в течение нескольких секунд или минут, то лучше воспользоваться сигналами readyReadStandardError()
и readyReadStandardOutput()
, организовав работу в асинхронном режиме.
Основным преимуществом этого кода является то, что вы можете не иметь библиотек и исходных кодов, которые обеспечивают соответствующий функционал. Однако производительность снижается, поэтому если скорость работы критична, то придется искать альтернативные варианты решения.
Вы можете не только читать то, что приложение пишет в стандартные потоки вывода, но и сами писать в поток ввода процесса:
void writeReadTest() {
QProcess process;
process.start( "cat" );
if( !process.waitForStarted() ) {
return;
}
process.write( "Hello, world!" );
process.closeWriteChannel();
if( !process.waitForFinished() ) {
return;
}
qDebug() << process.readAllStandardError();
qDebug() << process.readAllStandardOutput();
}
Принцип работы этого примера очень похож на то, что мы видели раньше. Однако теперь внешнее приложение реагирует на то, что мы подаем ему в поток ввода stdin
. Все, что мы отправляем в cat
, вернется нам обратно в результате вызова readAllStandardOutput()
. Обратите внимание, что завершение процесса происходит после вызова closeWriteChannel()
(равносильно нажатию Ctrl+D
).
Мы рассмотрели два базовых способа использования QProcess
. Возможно, в вашей работе они никогда и не понадобятся, но знать о них не будет лишним.
Здравствуйте. Спасибо за комментарий.
Если Вас интересуют вопросы информационной безопасности, то можете обратиться к книгам 24 смертных греха компьютерной безопасности. Библиотека программиста и Как написать безопасный код на C++ Java Perl PHP ASP.NET.
Если же речь идет именно о работе с потоками в целом, то могу посоветовать книгу Параллельное программирование на С++ в действии. Книга посвящена параллельному программированию на C++11, но очень полезна и с теоретической точки зрения, поскольку в ней рассматриваются все основные вопросы о работе с потоками.
А есть какая-нибудь возможность узнать координаты и размеры запущенного приложения? Лучше, если в linux
Anonymous:
А есть какая-нибудь возможность узнать координаты и размеры запущенного приложения? Лучше, если в linux
Т.е. требуется найти путь к файлу на диске и размер, занимаемый приложением в RAM, по имени процесса?
Mikhail:
Anonymous:
А есть какая-нибудь возможность узнать координаты и размеры запущенного приложения? Лучше, если в linux
Т.е. требуется найти путь к файлу на диске и размер, занимаемый приложением в RAM, по имени процесса?
Нет. Некорректно написал. Имеется в виду визуальное представление (координаты окна и его визуальный размер). В windows можно было использовать функцию FindWindow, а затем уже по полученному дескриптору запросить все остальное. А вот в linux не могу найти, как сделать подобное. Понятно, что это будет зависеть от оконного менеджера.
Это все необходимо для создания бота. Управление мышью уже сделал а вот с координатами пока проблема…
Anonymous:
Нет. Некорректно написал. Имеется в виду визуальное представление (координаты окна и его визуальный размер). В windows можно было использовать функцию FindWindow, а затем уже по полученному дескриптору запросить все остальное. А вот в linux не могу найти, как сделать подобное. Понятно, что это будет зависеть от оконного менеджера.
Да, я понял. Этого можно добиться с помощью XLib. В ближайшие дни постараюсь подготовить небольшую статью на эту тему.
Виталий
Дообрый день. Спасибо за очень полезные обучающие статьи! Расскажите, пожалуйста подробнее (или скажите где можно об этом почитать):
Цитата: "Нельзя забывать, что он еще и весьма опасен. Однако здесь мы не будем затрагивать вопросы информационной безопасности, а лишь ограничимся базовыми приемами…".
Мне очень интересно было бы разобраться в вопросах безопасности потоков.