Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > real-time console redirect on windows


Автор: lomantik 25.8.2011, 16:22
Здравствуйте! Пишу от безысходности. Не могу перенаправить вывод консольного приложения на графический интерфейс. Консоль выполняет python-скрипт. Графика написана с использованием GTK, запускает вышеозначенное консольное приложение и выводит перехваченный stdout в текстовое поле. Под linux сие реализовать получилось. Под windows, нет. В том смысле, что вывод перехватывается, но весь сразу под конец работы консоли, а нужно получать его в процессе ее (консоли) работы. Если у кого то есть варианты решения, очень прошу поделиться.

Автор: _GRIN_ 26.8.2011, 12:25
lomantik, топорное решение - перенаправлять из питона вывод в файл - переодически опрашивать файл вывода - а предмет новой порции данных.
Можно копать в сторону pipe & windows.

Автор: lomantik 29.8.2011, 16:38
Разобрался. Спасибо. Но возникла новая проблема. О ней в новой теме..

Автор: borisbn 30.8.2011, 11:31
Цитата(lomantik @  29.8.2011,  16:38 Найти цитируемый пост)
Разобрался. Спасибо.

колись. тоже интересно.

или так, как посоветовал _GRIN_ ?

Автор: lomantik 8.9.2011, 13:00
Все решил, но отписаться было некогда. Короче, вот решение под windows:

Функция создания отдельного процесса с перехватываемым выводом stdout и stderr:
Код

HANDLE hOutput, hProcess;

HANDLE SpawnAndRedirect(LPCTSTR commandLine, HANDLE stdOutputReadPipe, LPCTSTR currentDirectory)
{
    HANDLE stdOutputWritePipe, stdOutput, stdError;
    CreatePipe(stdOutputReadPipe, &stdOutputWritePipe, NULL, 0);
    DuplicateHandle(GetCurrentProcess(), stdOutputWritePipe, GetCurrentProcess(), &stdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
    DuplicateHandle(GetCurrentProcess(), stdOutput, GetCurrentProcess(), &stdError, 0, TRUE, DUPLICATE_SAME_ACCESS);
    CloseHandle(stdOutputWritePipe);
    
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    si.hStdOutput = stdOutput;
    si.hStdError = stdError;
    si.wShowWindow = SW_HIDE;
    TCHAR commandLineCopy[1024];
    strcpy(commandLineCopy, commandLine);
    if(!CreateProcess(NULL, commandLineCopy, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, currentDirectory, &si, &pi))
    {
        CloseHandle(stdOutput);
        CloseHandle(stdError);
        CloseHandle(stdOutputReadPipe);
        stdOutputReadPipe = INVALID_HANDLE_VALUE;
        return NULL;
    }
    
    CloseHandle(pi.hThread);
    CloseHandle(stdOutput);
    CloseHandle(stdError);
    return pi.hProcess;
}


Запуск консольного приложения:
Код

...
    hProcess = (HANDLE)SpawnAndRedirect("console_app.exe", &hOutput, NULL);
    if(!hProcess) return;
...


Функция перехвата:
Код

void *thread_function(void *threadid)
{
    char buffer[1024];
    DWORD read;
    
    while(ReadFile(hOutput, buffer, 1024, &read, NULL))
    {
        gtk_text_buffer_insert_at_cursor(text_buffer1, buffer, read);
    }
    CloseHandle(hOutput);
    CloseHandle(hProcess);
}


Запуск функции перехвата в отдельном потоке:
Код

...
    rc = pthread_create(&mthread, NULL, thread_function, NULL);
...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)