Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват stdout у DOS программ 
:(
    Опции темы
albertn
Дата 28.1.2012, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Доброго времени суток!

Есть исходный код, который запускает процесс и перенаправляет его вывод в файл:
Код

#include <windows.h>
#include <stdio.h>

int main()
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    STARTUPINFO si;
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = TEXT("");
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;;
    si.wShowWindow = SW_HIDE;
    HANDLE hFile = CreateFile ("c:\\output.txt", GENERIC_WRITE, FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL);
    si.hStdOutput = hFile;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    BOOL create_ok;
    create_ok = CreateProcess(NULL,"C:\\1.exe",NULL,NULL,TRUE,CREATE_NEW_CONSOLE | CREATE_SEPARATE_WOW_VDM,NULL,"C:\\",&si,&pi);
    if (!create_ok)
    {
        printf("Run fail\n");
        return 0;
    }
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(hFile);
}


Он отлично работает для консольных win32 программ, но для DOS программ он ничего не записывает в выходной файл. Замечено, что если не указывать флаг CREATE_NEW_CONSOLE, то программа работает верно, но это не выход.

Может кто знает как решить проблему?
PM WWW ICQ   Вверх
Dem_max
Дата 28.1.2012, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39





--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
albertn
Дата 28.1.2012, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(Dem_max @ 28.1.2012,  16:32)
Перехват консольного вывода

С пайпами аналогичная ситуация.
PM WWW ICQ   Вверх
Dem_max
Дата 28.1.2012, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Цитата

Замечено, что если не указывать флаг CREATE_NEW_CONSOLE, то программа работает верно, но это не выход.

Почему не выход ?????


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
albertn
Дата 28.1.2012, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(Dem_max @ 28.1.2012,  16:44)
Цитата

Замечено, что если не указывать флаг CREATE_NEW_CONSOLE, то программа работает верно, но это не выход.

Почему не выход ?????

Фактически программа работает как сервис, внутри которого в несколько потоков происходит запуск программ. Необходимо чтобы выполнение программ не влияло друг на друга и на сервис в целом. Как я понимаю, флаг CREATE_NEW_CONSOLE гарантирует это.
PM WWW ICQ   Вверх
Dem_max
Дата 29.1.2012, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Попробуй без этого флага, но используй функции AllocConsole, AttachConsole


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 29.1.2012, 12:16 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(albertn @  28.1.2012,  16:48 Найти цитируемый пост)
Необходимо чтобы выполнение программ не влияло друг на друга и на сервис в целом. Как я понимаю, флаг CREATE_NEW_CONSOLE гарантирует это. 

Перебейте запускаемым программам все потоки ввода вывода (stdin/stdout/stderr), и они так же не будут влиять друг на друга и без CREATE_NEW_CONSOLE

PM MAIL   Вверх
albertn
Дата 2.2.2012, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(xvr @ 29.1.2012,  12:16)
Цитата(albertn @  28.1.2012,  16:48 Найти цитируемый пост)
Необходимо чтобы выполнение программ не влияло друг на друга и на сервис в целом. Как я понимаю, флаг CREATE_NEW_CONSOLE гарантирует это. 

Перебейте запускаемым программам все потоки ввода вывода (stdin/stdout/stderr), и они так же не будут влиять друг на друга и без CREATE_NEW_CONSOLE

Выяснилась еще одна особенность, что при использовании CreateProcessAsUser для DOS программ без CREATE_NEW_CONSOLE вываливается ошибка "Неверный дескриптор." при перенаправлении. Тут я уже не знаю что делать :(

Приведу фрагмент кода, на котором происходит ошибка:
Код

#include <windows.h>
#include <stdio.h>

char* getErrorDescription(int error) {
    char *buf = 0;
    FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
      0,
      error,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) &buf,
      0,
      NULL);
    char* res = strdup(buf);
    LocalFree(buf);
    return res;
}

int main()
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    STARTUPINFO si;
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = TEXT("");
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;;
    si.wShowWindow = SW_HIDE;
    HANDLE hFile = CreateFile ("c:\\output.txt", GENERIC_WRITE, FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL);
    si.hStdOutput = hFile;
    si.hStdError = hFile;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    HANDLE hUser;
    if (!LogonUser("user",TEXT("."),"password",LOGON32_LOGON_BATCH,LOGON32_PROVIDER_DEFAULT,&hUser))
    {
        printf("Login error %s\n",getErrorDescription(GetLastError()));
        return 0;
    }
    BOOL create_ok;
    create_ok = CreateProcessAsUser(hUser,NULL,"C:\\1.exe",NULL,NULL,TRUE,CREATE_SEPARATE_WOW_VDM/* | CREATE_NEW_CONSOLE*/,NULL,"C:\\",&si,&pi);
    if (!create_ok)
    {
        printf("Run error %s\n",getErrorDescription(GetLastError()));
        return 0;
    }
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(hFile);
    CloseHandle(hUser);
}


Может все-же дело в XP?

Добавлено через 2 минуты и 23 секунды
Цитата(Dem_max @ 29.1.2012,  09:19)
Попробуй без этого флага, но используй функции AllocConsole, AttachConsole

Это не решит проблему.
PM WWW ICQ   Вверх
xvr
Дата 2.2.2012, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Попробуйте создать открытый для всех Security Descriptor и записать его в sa.lpSecurityDescriptor, возможно процессу банально не хватает прав

PM MAIL   Вверх
albertn
Дата 3.2.2012, 08:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(xvr @ 2.2.2012,  18:14)
Попробуйте создать открытый для всех Security Descriptor и записать его в sa.lpSecurityDescriptor, возможно процессу банально не хватает прав

Добавил в начало следующие строчки:
Код

    SECURITY_DESCRIPTOR sd;
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, TRUE);
    sa.lpSecurityDescriptor = &sd;

Результат работы остался тем-же.

Добавлено через 9 минут и 25 секунд
Кстати, оказывается без флага CREATE_NEW_CONSOLE программа выполняется и выводит в текстовый файл данные, но почему-то CreateProcessAsUser возвращает ошибку.

PS. Консольные win32 программы работают как надо при любых параметрах.
PM WWW ICQ   Вверх
xvr
Дата 3.2.2012, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(albertn @  3.2.2012,  08:29 Найти цитируемый пост)
Кстати, оказывается без флага CREATE_NEW_CONSOLE программа выполняется и выводит в текстовый файл данные, но почему-то CreateProcessAsUser возвращает ошибку.

А может ей не нравится NULL в si.hStdIn (кстати - NULL это валидный дескриптор файла)? Попробуйте открыть NUL и передать туда

PM MAIL   Вверх
albertn
Дата 3.2.2012, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(xvr @ 3.2.2012,  11:21)
Цитата(albertn @  3.2.2012,  08:29 Найти цитируемый пост)
Кстати, оказывается без флага CREATE_NEW_CONSOLE программа выполняется и выводит в текстовый файл данные, но почему-то CreateProcessAsUser возвращает ошибку.

А может ей не нравится NULL в si.hStdIn (кстати - NULL это валидный дескриптор файла)? Попробуйте открыть NUL и передать туда

Результат тот-же.
PM WWW ICQ   Вверх
xvr
Дата 3.2.2012, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



А попробуйте CREATE_NO_WINDOW или DETACHED_PROCESS вместо CREATE_NEW_CONSOLE

PM MAIL   Вверх
albertn
Дата 3.2.2012, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(xvr @ 3.2.2012,  12:11)
А попробуйте CREATE_NO_WINDOW или DETACHED_PROCESS вместо CREATE_NEW_CONSOLE

Выбивает ту-же ошибку.
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1518 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.