#c #winapi
#c #winapi
Вопрос:
Я хочу, чтобы автоматическая проверка была плохой или хорошей для запуска моих файлов .exe. Например, для этих двоичных файлов у меня отсутствуют dll, и когда я использую CreateProcess, он не возвращает ошибку и не предоставляет мне системное окно сообщений («Dll отсутствует»). Если я закрою его вручную, методы вернут код выхода STATUS_DLL_NOT_FOUND . Я хочу, чтобы по истечении некоторого времени ожидания все системные окна сообщений были закрыты с закрытием родительского процесса, и я могу получить свой STATUS_DLL_NOT_FOUND. Мне нужна полная автоматическая работа с моим кодом.Этот код может закрывать открытые вложенные диалоги, но не может закрывать ящики сообщений.
int main()
{
HANDLE hJob;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
hJob = CreateJobObject(NULL, NULL);
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, amp;jeli, sizeof(jeli));
TCHAR szCmdline[] = TEXT(" -R:mm");
si.cb = sizeof(si);
CreateProcess(
executableFiles[0].c_str(),
szCmdline,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB /*Important*/,
NULL,
NULL,
amp;si,
amp;pi);
AssignProcessToJobObject(hJob, pi.hProcess); // Does not work if without CREATE_BREAKAWAY_FROM_JOB
ResumeThread(pi.hThread);
if (WaitForSingleObject(pi.hProcess, 3000) == WAIT_TIMEOUT)
{
EnumWindows(amp;SendWMCloseMsg, pi.dwProcessId);
if (WaitForSingleObject(pi.hProcess, 2000) == WAIT_TIMEOUT)
{
TerminateProcess(pi.hProcess, 0);
DWORD dwExitCode = 0;
GetExitCodeProcess(pi.hProcess, amp;dwExitCode);
const DWORD result = WaitForSingleObject(pi.hProcess, 2000);
if (result == WAIT_OBJECT_0)
{
if (dwExitCode == STATUS_DLL_NOT_FOUND)
{
std::cout << "Dll is missing" << std::endl;
}
}
else
{
std::cout << "bad case" << std::endl;
}
}
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hJob);
return 0;
}
Ответ №1:
Вызовите UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
before CreateProcess
и убедитесь, что CREATE_DEFAULT_ERROR_MODE
это не задано в dwCreationFlags
параметре, чтобы дочерний процесс унаследовал режим ошибки родительского процесса. Согласно документам, это «не отображает окно сообщения обработчика критических ошибок, вместо этого система отправляет ошибку вызывающему процессу«.
Необязательно SetErrorMode(oldErrorMode);
после CreateProcess
восстановления предыдущей настройки.