OutputDebugStringA
会触发异常 DBG_PRINTEXCEPTION_C
(在 win10 中的 W
版本为 DBG_PRINTEXCEPTION_WIDE_C
),并带有两个参数 - (字符串长度(以字符为单位)+1,字符串指针)。结果我们可以自己处理这个异常(系统默认处理程序对于此异常执行 this)。
将 OutputDebugString
重定向到控制台的示例处理程序:
LONG NTAPI VexHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
switch (ExceptionRecord->ExceptionCode)
{
case DBG_PRINTEXCEPTION_WIDE_C:
case DBG_PRINTEXCEPTION_C:
if (ExceptionRecord->NumberParameters >= 2)
{
ULONG len = (ULONG)ExceptionRecord->ExceptionInformation[0];
union {
ULONG_PTR up;
PCWSTR pwz;
PCSTR psz;
};
up = ExceptionRecord->ExceptionInformation[1];
HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
if (ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
{
if (ULONG n = MultiByteToWideChar(CP_ACP, 0, psz, len, 0, 0))
{
PWSTR wz = (PWSTR)alloca(n * sizeof(WCHAR));
if (len = MultiByteToWideChar(CP_ACP, 0, psz, len, wz, n))
{
pwz = wz;
}
}
}
if (len)
{
WriteConsoleW(hOut, pwz, len - 1, &len, 0);
}
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
而要设置此处理程序,需要调用:
AddVectoredExceptionHandler(TRUE, VexHandler);
像这里描述的那样,OutputDebugString
的系统实现实际上是使用完全相同的参数调用RaiseException
,只不过在异常处理程序中而不是MessageBox
中 - 代码在这里描述。
VEX
处理程序并监视DBG_PRINTEXCEPTION_[WIDE_]C
。如果你想要,我可以粘贴代码将OutputDebugString
重定向到控制台,这很简单。 - RbMm