CreateProcess ждет, когда исполняемый файл недействителен

Я хочу создать простую программу на C++, которая одновременно запускает несколько исполняемых файлов, используя Создать процесс. Если exe-файл недействителен (заполнен случайными данными), появляется окно сообщения и говорится, что файл не совместим с 64-битной Windows, что нормально, но моя программа ждет, пока окно сообщения не закроется. Есть ли способ обойти это?


person Community    schedule 19.11.2015    source источник


Ответы (1)


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

SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS  
  | SEM_NOOPENFILEERRORBOX);

Я считаю, что SEM_FAILCRITICALERRORS - это флаг, относящийся к вашей текущей проблеме, но вы должны включить и другие.

Обратите внимание, что, по крайней мере, в более старых версиях Windows, нет функции для простого получения текущего режима ошибки. Функция GetErrorMode была добавлена ​​в Vista. Поэтому вместо этого мы вызываем SetErrorMode(0), который возвращает предыдущий режим ошибки. Этот несколько неудобный дизайн API обсуждается в статье Рэймонда Чена здесь: Отключение диалогового окна сбоя программы. Конечно, если вы больше не поддерживаете XP, вы можете использовать:

SetErrorMode(GetErrorMode() | SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS  
  | SEM_NOOPENFILEERRORBOX);
person David Heffernan    schedule 19.11.2015
comment
Спасибо, это работает! Но разве мы не можем просто вызвать GetErrorMode, чтобы получить oldMode? - person ; 19.11.2015
comment
Вы можете, если вы нацелены на Vista и более поздние версии. - person David Heffernan; 19.11.2015
comment
В Windows 7 предупреждение безопасности об открытии загруженных исполняемых файлов также приостанавливает работу программы. Есть ли способ обойти это (сейчас я использую ShellExecute, если это не так)? - person ; 19.11.2015
comment
Вы можете удалить альтернативный файловый поток, указывающий, что файл был загружен из внешнего источника. - person David Heffernan; 19.11.2015
comment
Обратите внимание, что в Win7+ также есть SetThreadErrorMode(). Да, вы должны вызвать SetErrorMode() при запуске, чтобы отключить диалоги ошибок для всего процесса. Но давайте посмотрим правде в глаза, сколько людей на самом деле делают это? Сколько людей вообще осознают, что Set(Thread)ErrorMode() вообще существуют? В качестве альтернативы вы можете использовать SetThreadErrorMode() для настройки только потока, который вызывает CreateProcess() (если он отличается от основного потока) в качестве обходного пути без изменения поведения всего приложения. - person Remy Lebeau; 19.11.2015
comment
@Remy Я вызываю SetErrorMode. Это довольно легко сделать. Вы предлагаете нам не делать этого? Изменение поведения приложения — это именно то, что нужно. - person David Heffernan; 19.11.2015
comment
@DavidHeffernan: я сказал, что мы должны. Хорошо для вас, если вы это делаете, но не для всех остальных. - person Remy Lebeau; 19.11.2015