Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/34: Рейтинг темы: голосов - 34, средняя оценка - 4.56
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230

Запустить внешнее консольное приложение и вернуть результат

07.05.2016, 01:26. Показов 6532. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Подскажите, пожалуйста, как можно запустить внешнее консольное приложение без создания окна и вернуть результат? Например вызвав ping.exe получить вывод в своей программе.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.05.2016, 01:26
Ответы с готовыми решениями:

Как запустить внешнее консольное приложение и получить то, что будет выведено на экран?
Есть программка которая распознает капчу, когда я ее запускаю из командной строки выводится значение капчи на экран от так вызываю да...

Запустить внешнее приложение, передать ему параметры и получить результат
Здравствуйте. Проблема такая: RunCommand(exe_name,,output); Думаю, что такое exe_name и exe_param, пояснять не надо) Дебаг показал,...

Как java-приложение может попросить OS запустить внешнее приложение?
Как java-приложение может попросить OS запустить внешнее приложение?

4
29 / 29 / 18
Регистрация: 20.12.2010
Сообщений: 119
07.05.2016, 15:35
Лучший ответ Сообщение было отмечено DarkMasterW как решение

Решение

перед выводом будет небольшая задержка(из-за ping)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <string>
 
std::string exec(const char* cmd) {
    char buffer[128];
    std::string result = "";
    FILE* pipe = _popen(cmd, "r");
    if (!pipe) throw std::runtime_error("popen() failed!");
    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != NULL)
            result += buffer;
    }
    _pclose(pipe);
    return result;
}
 
int main() {
 
    std::cout << exec("ping 8.8.8.8");
 
    std::cin.get();
    return 0;
}
2
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
24.05.2016, 15:48  [ТС]
Что произойдет при открытии pipe и невыполнении чтения? При большом потоке данных и отсрочке чтения, насколько я понимаю, все должно падать в буфер ОС. Есть какие-то стандарты поведения, объем буфера и т.д.?
0
29 / 29 / 18
Регистрация: 20.12.2010
Сообщений: 119
24.05.2016, 16:35
Насколько я понял при вызове popen создается pipe (i/o поток), размером по-умолчанию в 65536 байт (размер зависит от реализации в ОС), реальный размер можно получить через fcntl с F_GETPIPE_SZ. Чтение из pipe это по сути чтение из стандартного потока вывода команды cmd. Если чтение не произведено, то при закрытии pipe буфер будет очищен.
http://man7.org/linux/man-pages/man3/popen.3.html про чтение
http://man7.org/linux/man-pages/man7/pipe.7.html смотри главу "Pipe capacity" и "I/O on pipes and FIFOs"
http://man7.org/linux/man-pages/man2/fcntl.2.html глава "Changing the capacity of a pipe"
В винде все примерно тоже самое.
1
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
24.05.2016, 22:21  [ТС]
Потребовалась двусторонняя связь. Вечер убит вникуда... В rw открыть pipe, как я понял невозможно, нужно через создание процесса создавать два pipe'а. Шаг в сторону и одни грабли:
С пингом работает, но если используем netsh /?\r\n в качестве параметра, то вернет "команда не найдена", хотя должно вывести хелп.
При этом если в атрибутах запуска присутствует флаг STARTF_USESTDHANDLES, то сразу после запуска netsh будет завершен, хотя он должен остаться висеть и ожидать команды. Убираем флаг STARTF_USESTDHANDLES, в процессах висит, но при этом теряем связь через pipe.
Использование WriteFile не привело к каким-либо результатам вообще.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
CStringA ExecCmd(
    const char* cmd              // [in] command to execute
    )
{
    CStringA strResult;
    HANDLE hPipeRead, hPipeWrite;
 
    SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
    saAttr.bInheritHandle = TRUE;   //Pipe handles are inherited by child process.
    saAttr.lpSecurityDescriptor = NULL;
 
    // Create a pipe to get results from child's stdout.
    if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
        return strResult;
 
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdOutput = hPipeWrite;
    si.hStdError = hPipeWrite;
    si.wShowWindow = SW_HIDE;       // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags.
 
    PROCESS_INFORMATION pi = { 0 };
 
    BOOL fSuccess = CreateProcessA(NULL, (LPSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    if (!fSuccess)
    {
        CloseHandle(hPipeWrite);
        CloseHandle(hPipeRead);
        return strResult;
    }
 
    //Sleep(5000);
    //char buf_write[] = "/?\r\n\0";
    //DWORD dwWrite = 0;
    //if (!::WriteFile(hPipeWrite, buf_write, strlen(buf_write), &dwWrite, NULL) || !dwWrite)
    //  cout << "write error" << endl;
    //cout << "dwWrite" << dwWrite << endl;
 
    bool bProcessEnded = false;
    for (; !bProcessEnded;)
    {
        // Give some timeslice (50ms), so we won't waste 100% cpu.
        bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;
 
        // Even if process exited - we continue reading, if there is some data available over pipe.
        for (;;)
        {
            char buf[1024];
            DWORD dwRead = 0;
            DWORD dwAvail = 0;
 
            if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL))
                break;
 
            if (!dwAvail) // no data available, return
                break;
 
            if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead)
                // error, the child process might ended
                break;
 
            buf[dwRead] = 0;
            strResult += buf;
        }
    } //for
 
    CloseHandle(hPipeWrite);
    CloseHandle(hPipeRead);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return strResult;
} //ExecCmd
 
 
void main(){
    std::cout << "result: \n" << ExecCmd("netsh");
    _getch();
    return;
}
Прошу помочь...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.05.2016, 22:21
Помогаю со студенческими работами здесь

Как из Vb.Net запустить внешнее приложение
Помогите пожалуйста новичку. Мне нужно из vb.net запустить Crystal Reports (не компонент vb) и передать ему управление. По завершению...

Запустить консольное приложение в Windows 7
Всем привет. Я написал консольное приложение на Visual C++ 2008 Express по минимизации логических функций. У меня дома (операционка...

Программно запустить консольное приложение
Помогите разобраться с кодом есть консольное приложение. Мне нужно чтоб его можно было запускать внешним приложением. Дело в том, что если...

Запустить и скрыть консольное приложение
Всем привет. У меня есть функция для запуска программ function StartProccess(filepath: string; const CommandLine: string): DWORD; ...

Скомпилировать и запустить консольное приложение
Как скомпилировать код чтобы его можно было запустить с консоли. Пытался много раз и на этом сайте тоже, но не выходит. Я хочу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru