окей ... сгорел на этом ... чесал голову весь день.У меня есть очень простая, одноразовая c ++ DLL (StartApplication.dll), используемая для запуска приложения.
- Прекрасно работает в WinXP, но не в win7
- Использует CreateProcess () с DEBUG_PROCESS (поэтому я могу дождаться завершения программы перед завершением).
- Если я наблюдаю за процессами в диспетчере задач, я вижу, как запускается процесс, но окно не создается, и больше ничего не происходит
- Если я изменю на NORMAL_PRIORITY_CLASS, программа будет выполняться так, как должна (но я теряю способностьподождите, прежде чем завершить, поскольку я могу сделать это только во время отладки)
- Код ошибки дает мне STATUS_ACCESS_VIOLATION
- У меня отключен контроль учетных записей, и настройка исполняемого файла на запуск от имени администратора и совместимость с WinXP ничего не делает
Вот код.Любые мысли будут с благодарностью
//...blah blah...handful of stuff preceding this to set up command line and
//directories etc....not of use here probably...
SECURITY_ATTRIBUTES sa = {0}; sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
STARTUPINFO si = {0}; si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = (NULL == stdOutFileName)? INVALID_HANDLE_VALUE :
::CreateFile(stdOutFileName, GENERIC_WRITE, FILE_SHARE_READ, &sa
, CREATE_ALWAYS, 0, NULL);
si.hStdError = (NULL == stdErrFileName)? INVALID_HANDLE_VALUE :
::CreateFile(stdErrFileName, GENERIC_WRITE, FILE_SHARE_READ, &sa
, CREATE_ALWAYS, 0, NULL)
PROCESS_INFORMATION pi = {0};
if (::CreateProcess(useApplicationName? applicationName : NULL, processCommandLine
, NULL, NULL, TRUE, /*NORMAL_PRIORITY_CLASS*/DEBUG_PROCESS, NULL, currentDirectory, &si, &pi))
{
BOOL cont = TRUE;
while (cont)
{
DWORD continueStatus = DBG_CONTINUE;
DEBUG_EVENT debugEvent = {0};
if (!::WaitForDebugEvent(&debugEvent, INFINITE))
{
errorCode = ErrorCode_Other;
::TerminateProcess(pi.hProcess, 0);
break;
}
else
{
switch (debugEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
switch (debugEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_DATATYPE_MISALIGNMENT:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_PRIV_INSTRUCTION:
case EXCEPTION_IN_PAGE_ERROR:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
case EXCEPTION_STACK_OVERFLOW:
case EXCEPTION_INVALID_DISPOSITION:
case EXCEPTION_INVALID_HANDLE:
errorCode = ErrorCode_ApplicationException;
*exceptionCode = debugEvent.u.Exception.
ExceptionRecord.ExceptionCode;
::TerminateProcess(pi.hProcess, 0);
break;
default:
;
}
break;
case EXIT_PROCESS_DEBUG_EVENT:
cont = FALSE;
break;
default:
;
}
::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId
, continueStatus);
}
}
::GetExitCodeProcess(pi.hProcess, reinterpret_cast<LPDWORD>(exitCode));
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
if (INVALID_HANDLE_VALUE != si.hStdOutput)
::CloseHandle(si.hStdOutput);
if (INVALID_HANDLE_VALUE != si.hStdError)
::CloseHandle(si.hStdError);
return errorCode;
}