OutputDebugString()在控制台中的使用

8
我正在使用一个第三方库,它使用函数OutputDebugString(),阅读MSDN文档时似乎表明该函数是用于向调试器打印输出。

但在我的情况下,这很不方便,是否有一种方法可以在没有连接调试器的情况下读取此输出?

如果这是我的LIB,我会更喜欢每当用户传递--debug或类似参数时将输出发送到stdout/stderr,但由于这不是我在寻找其他将此信息传递到控制台(或文件)的方法,而不需要连接调试器。


2
尝试使用Dbgview,它可以捕获输出字符串,并具有许多其他功能。 - Tiger Hwang
1
如果你想以编程方式读取此输出,这是可能的。你需要设置VEX处理程序并监视DBG_PRINTEXCEPTION_[WIDE_]C。如果你想要,我可以粘贴代码将OutputDebugString重定向到控制台,这很简单。 - RbMm
@RbMm 当然 - 那可能会很有用。 - Zitrax
尝试使用[DebugView++](https://github.com/CobaltFusion/DebugViewPP/releases)。它比DebugView快得多,并且具有一些非常有用的格式化和过滤选项。 - rossmcm
1个回答

9

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)
            {
                // localized text will be incorrect displayed, if used not CP_OEMCP encoding 
                // WriteConsoleA(hOut, psz, len, &len, 0);

                // assume CP_ACP encoding
                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中 - 代码在这里描述。


你的解决方案不起作用。OutputDebugString 不会生成你提到的异常。 - Sonny D
1
你是对的,我错了。确实生成了 DBG_PRINTEXCEPTION_WIDE_C。我再次测试了一下,我犯了错误。抱歉。我不会删除以前的评论,以免混淆其他人。 - Sonny D
1
@SonnyD - 我几乎确定你是在调试器下测试的。当然会生成异常,在这种情况下,但调试器会处理此异常,因此您不会在代码中看到它。异常处理程序未被调用。 - RbMm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接