控制台中的 OutputDebugString()

Posted

技术标签:

【中文标题】控制台中的 OutputDebugString()【英文标题】:OutputDebugString() in console 【发布时间】:2017-01-04 14:17:12 【问题描述】:

我正在使用使用函数OutputDebugString() 的第三方库,并且在阅读 MSDN 文档时似乎表明这是用于打印到调试器。

但这对我来说很不方便,如果没有连接调试器,有没有办法读取这个输出?

如果它是我的 LIB,我希望每当用户通过 --debug 或类似参数时将输出转到 stdout/stderr,但由于不是我正在寻找其他方法将此信息传递到控制台(或文件) 无需连接调试器。

【问题讨论】:

试试dbgview,它会捕获输出字符串,还有很多其他功能 如果你想这样做 "* read this output *" programmatically - 这是可能的 - 你需要为DBG_PRINTEXCEPTION_[WIDE_]C设置VEX处理程序和间谍 - 如果你愿意我可以粘贴代码重定向@ 987654327@ 到控制台 - 这是小而简单的 @RbMm 当然 - 这可能很有用。 试试DebugView++。比 DebugView 快得多,并且有一些非常有用的格式化和过滤选项。 【参考方案1】:

OutputDebugStringA 生成异常 DBG_PRINTEXCEPTION_C(win10 中的W 版本 - DBG_PRINTEXCEPTION_WIDE_C),带有 2 个参数 -(字符串长度,字符 + 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 的系统实现类似于here - 它确实使用这个参数调用了RaiseException,只是在异常处理程序中而不是MessageBox - 代码描述为here。

【讨论】:

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

以上是关于控制台中的 OutputDebugString()的主要内容,如果未能解决你的问题,请参考以下文章

log4cxx OutputDebugString DebugView dbgview

Delphi和OutputDebugString

有关OutputDebugString的一点儿事实

将 OutputDebugString 记录到文件中(没有 DebugView)

如何从服务接收 OutputDebugString?

DebugView 使用