好的......燒壞了這個......整天都在撓我的腦袋。我有一個非常簡單的單用途C++ DLL(StartApplication.dll),用於啓動應用程序。Windows 7 - CreateProcess w/DEBUG_PROCESS訪問衝突
- 在WinXP中工作正常,但不是在Win7
- 使用的CreateProcess()與DEBUG_PROCESS(這樣我就可以等待程序結束前完成)。
- 如果我監視任務管理器進程,我可以看到進程的開始,但沒有創建窗口,並沒有進一步發生
- 如果我改變NORMAL_PRIORITY_CLASS,該方案將作爲其應該執行(但我失去的能力,終止,因爲我只能做到這一點的同時調試)
- 錯誤代碼給我STATUS_ACCESS_VIOLATION前等着
- 我有UAC關閉,設定可執行以管理員身份運行,並與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;
}
@Ajay:我添加了「.dwFirstChance!= 0」條件,在EXCEPTION_DEBUG_EVENT開關中的終止之前設置continueStatus。它只是做另一個循環,並在下一個循環終止。我自己編寫了一個新手(我原本沒有寫這個),所以如果我把它放在一個不好的地方,那麼讓我知道。 (或者如果有一部分流程我可以完全乾掉)。如果我重新排列的東西,我可以讓cmd窗口根據需要彈出,但它會掛起,直到終止時纔會執行任何操作。可能我需要設置某種Windows 7權限才能正確執行? – 0xDEADFACE 2012-01-12 16:15:48
@ 0xDEADFACE更新了我的答案,希望澄清一點。 – pezcode 2012-01-12 16:35:10
啊,我們走了。處理INT3異常是那裏的缺失鏈接。不得不稍微調整一下,以便優雅地處理終止事件,但這很像一種魅力。感謝一羣人。 – 0xDEADFACE 2012-01-12 19:17:23