155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
1

Завершение дочернего процесса по ошибке

24.03.2013, 15:37. Показов 4584. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Например, я запускаю дочерний процесс 1.ехе и ожидаю его окончания:
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
#include <windows.h>
#include <iostream>
using namespace std;
 
int main()
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    WCHAR* name = L"1.exe";
    
ZeroMemory( &si, sizeof(si) );
ZeroMemory( &pi, sizeof(pi) );
     
cout << "start a child process" << endl;
 
CreateProcess(
name,   //указатель на имя исполняемого файла
NULL,   //указатель на командную строку
NULL,   //указатель на  атрибуты безопасности процесса (Дескриптор процесса) 
NULL,   //указатель на  атрибуты безопасности потока (Дескриптор потока) 
FALSE,  //указатель на флаг наследования (Установка описателей наследования)
CREATE_NEW_CONSOLE,     //Флаги создания процесса
NULL,   //Указатель на новый блок среды (Блок переменных окружения родительского процесса)
NULL,   //указатель на имя текущего каталога (NULL-использовать текущий каталог родительского процесса)
&si,    // Указатель на структуру  STARTUPINFO.
&pi);     // Указатель на структуру информации о процессе.
 
    
// Ожидание окончания дочернего процесса
   WaitForSingleObject( pi.hProcess, INFINITE );
 
cout << "the end of the child process" << endl;
 
// Закрыть описатели процесса и потока 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
system("pause");
return 0;
}
Но как сделать, перехват исключений дочернего процесса? Т.е. как сделать чтобы дочерний процесс завершался при возникновении в нём ошибки выполнения и управление снова передавалось родительскому процессу?
Можно ли при этом обойтись без перехвата потоков ввода/вывода cerr?

Добавлено через 6 минут
(система Windows 7, среда VS 2010)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.03.2013, 15:37
Ответы с готовыми решениями:

Корректное завершение дочернего процесса
Я тестирую оконную программу - открываю и закрываю её несколько раз. Иногда программа завершается с...

Остановка дочернего процесса по его ошибке
В текущей директории имеется файл code.exe, которй принимает два числа и выводит их сумму....

Создание дочернего процесса
нужно создать дочерний процесс, чтобы если закрыть родительский закрылся и дочерний. но незнаю как...

Создание дочернего процесса
Уважаемые форумчане, у меня возник такой вопрос: Возможно ли средствами с++ создать дочерний...

13
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
24.03.2013, 15:49 2
по хендлу процесса можно определить его статус. и если он завершился, то и код его завершения тоже можно узнать. конкретную функцию к сожалению не помню.
0
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
24.03.2013, 18:05  [ТС] 3
Цитата Сообщение от DU Посмотреть сообщение
по хендлу процесса можно определить его статус. и если он завершился, то и код его завершения тоже можно узнать. конкретную функцию к сожалению не помню.
В том-то и дело, что дочерний процесс не завершился, а "завис", выводится диалоговое окно скодом ошибки, и нужно вручную его закрывать и т.д. и т.п...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
24.03.2013, 18:34 4
SetErrorMode с ключиком SEM_FAILCRITICALERRORS заставит дочерний процесс вернуть управление родительскому. Это нужно было?
1
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
24.03.2013, 18:53  [ТС] 5
Цитата Сообщение от UI Посмотреть сообщение
SetErrorMode с ключиком SEM_FAILCRITICALERRORS заставит дочерний процесс вернуть управление родительскому. Это нужно было?
Спасибо. Именно это и нужно.
0
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
25.03.2013, 19:56  [ТС] 6
Упс...
На сколько я смог разобраться, то SetErrorMode (независимо от ключей) лишь регулирует отображе6ние модальных окон.
А мне нужно, чтобы дочерний процесс "вылетал" при любой ошибке его выполнения...
Вот как это сделать... я не знаю.
А Вы?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
25.03.2013, 21:13 7
Можно пример кода для дочернего процесса, о котором ты говоришь, что он вешает у тебя выполнение основного процесса? Что там показывается за диалоговое окно, очень посмотреть хочется...
1
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
26.03.2013, 11:45  [ТС] 8
Ну, наверное всё таки, я не могу закрыть модальные окна.
ПРИМЕРЫ:
В Visual Studio 2010 создаю дочерний процесс:
C++
1
2
3
4
5
6
7
8
9
10
//1.exe
#include <iostream>
using namespace std;
int main()
{
    
    int i;
    cout << i << " ";
return 0;
}
Насильно (невзирая на замечание отладчика о выводе неинициализированной переменной) компилирую его. Запускаю откомпилированный файл 1.ехе из родительского процесса(код смотрите выше, в заголовочном сообщении).
В результате имею модальное окно отладчика Visual Studio, которое не исчезает ни при каких SetErrorMode() где бы его ни прописывал: хоть в родительском, хоть в дочернем процессе.

Подумал, что причина в компиляторе VS. Проделал подобное в CodeBlocks 10.05 (mingw32-gcc) . Здесь вышеуказанный дочерний процесс не останавливался модальным окном. Но дочерний процесс другого типа:
C++
1
2
3
4
5
6
7
8
9
10
11
//2.exe
#include <iostream>
using namespace std;
int main()
{
int i;
int M[]={1,2,3};
cin >> i;
cout << M[i];
return 0;
}
тоже висел с появлением модального окна при вводе 10-20 значных данных.
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
//для CodeBlocks 10.05 (mingw32-gcc)
#include <windows.h>
#include <iostream>
using namespace std;
 
int main()
{
    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    
    char* name = "2.exe";
    
ZeroMemory( &si, sizeof(si) );
ZeroMemory( &pi, sizeof(pi) );
     
cout << "start a child process" << endl;
//SetErrorMode(SEM_FAILCRITICALERRORS);
 
 
CreateProcess
    (   name,   //указатель на имя исполняемого файла
        NULL,   //указатель на командную строку
        NULL,   //указатель на  атрибуты безопасности процесса (Дескриптор процесса) (имеет смысл только в NT/2000) 
        NULL,   //указатель на  атрибуты безопасности потока (Дескриптор потока) (имеет смысл только в NT/2000)
        FALSE,  //указатель на флаг наследования (Установка описателей наследования). Если TRUE, то созданный процесс (запущенная программа), наследует дескрипторы (handles) запускающей программы
        CREATE_NEW_CONSOLE,     //Флаги создания процесса (класс приоритета и т.п.)
        NULL,   //Указатель на новый блок среды (окружения) (Блок переменных окружения родительского процесса. Если NULL, то используется блок окружения родителя)
        NULL,   //указатель на имя текущего каталога (NULL-использовать текущий каталог родительского процесса)
        &si,    // Указатель на структуру  STARTUPINFO, которая определяет положение главного окна
        &pi);   // Указатель на структуру информации о процессе.(сюда будет записана информация о созданном процессе)
 
    
    // Ожидание окончания дочернего процесса
 
    WaitForSingleObject( pi.hProcess, INFINITE );
 
cout << "the end of the child process" << endl;
SetErrorMode (0); 
 
    // Закрыть описатели процесса и потока 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
system("pause");
return 0;
}
Что я не так делаю? Как всё таки избавиться от модальных окон дочернего процесса?
Миниатюры
Завершение дочернего процесса по ошибке   Завершение дочернего процесса по ошибке  
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
26.03.2013, 13:16 9
Цитата Сообщение от LVV Посмотреть сообщение
Но дочерний процесс другого типа:
Прекрасно работает при вводе любого количества цифр (C::B 12.11)

Завершение дочернего процесса по ошибке

Завершение дочернего процесса по ошибке


Так как ошибку-то воспроизвести???
1
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
26.03.2013, 16:15  [ТС] 10
Странно. Почему же у меня не работает???
А не могли бы Вы дать свой код родительской проги, на которой всё "прекрасно работает"? Я вижу там отличия от моего кода.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
26.03.2013, 18:46 11
Да пожалуйста:
Вложения
Тип файла: zip testerr.zip (2.8 Кб, 31 просмотров)
1
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
26.03.2013, 19:33  [ТС] 12
Отличий, практически нет.

При запуске Вашего проекта - высвечивает диалоговое окно "Error" (3)

А с моим дочерним процессом высвечивает модальное окно при вводе значения 1000000000

Спасибо. Буду "колдовать" дальше, может что-нибудь придумаю.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
26.03.2013, 20:13 13
LVV, я-таки воспроизвел это окно... Замени в моем коде строку с SetErrorMode вот на такую:
C++
1
UINT errMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
(привык я к Алголоподобному синтаксису, что ж поделаешь, вот и написал автоматически or ), и окно перестанет появляться, вместо этого из дочернего процесса будет возвращаться ненулевой код ошибки:
start a child process
the end of the child process
exit code = 3221225477
, например...
1
155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750
27.03.2013, 10:40  [ТС] 14
Изменил строку. Результат тот же. Не пойму в чем дело. Модальное окно всё равно появляется.
Может попробовать перехватить исключения с помощью Catch? Правда, я в этом еще больший ноль, чем в SetErrorMode.

Добавлено через 13 часов 39 минут
Здравствуйте, UI.
Нашел причину "неудач". Оказывается всё дело в моей операционке. Что-то там не так настроено, или библиотек каких нибудь dll-овских недостаёт. В общем на других компах, и под Windows XP и под Windows 7 всё работает отлично. Дочерний процесс "вылетает" без всяких модальных окон. Еще раз спасибо за помощь.
0
27.03.2013, 10:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.03.2013, 10:40
Помогаю со студенческими работами здесь

Завершение дочернего процесса
Подскажите как правильно обработать завершение программы при вызове родителем QProcess::close()...

Завершение родительского процесса из дочернего
Всем доброго времени суток. Мне нужно из дочернего процесса закрыть родительский, но ничего не...

Завершение основной программы из дочернего потока _beginthread
Подскажите пожалуйста команду, которая закрывает основную программу из созданного потока

Правильное завершение потока при фатальной ошибке
Создаю поток через CreateThread(....), поток выполняется и в какой то момент в нем происходит...

Запуск дочернего процесса
Почему второй вариант не запускает дочерний процесс? // Работает CreateProcess(L&quot;programma.exe&quot;,...

Как изменить текст на форме из дочернего потока, когда в основном потоке ожидается завершение дочернего
Идея следующая. в основном потоке вызывают метод класса в другом потоке. Причем необходимо: 1....


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru