如何在不包含 Windows.h 的情况下获取 IsDebuggerPresent 的声明

How to get a declaration for IsDebuggerPresent without including Windows.h?

本文关键字:情况下 获取 IsDebuggerPresent 声明 Windows 包含      更新时间:2023-10-16
这与

如何安装 DebugBreak 处理程序有关?以及如何在不包含 Windows.h 的情况下获取 DebugBreak 的声明?。我们想评估使用IsDebuggerPresent()以避免在没有调试器的情况下使用DebugBreak()时崩溃。

我们遇到的问题是,我们必须包括<windows.h>,即使定义了WIN32_LEAN_AND_MEAN,它也会带来很多额外的麻烦。一些额外的问题,如minmax,破坏C++编译。事实上,测试我们的更改破坏了我们。

尝试使用简单的extern BOOL IsDebuggerPresent()来执行此操作需要大量的预处理器魔法,并且不匹配函数所有版本的签名。考虑到我们希望确保 15 年的操作系统和编译器"一切正常",这似乎是一个棘手的问题。

是否可以在不包含<windows.h>的情况下使用IsDebuggerPresent()?如果是这样,那么我们该怎么做?

下面的代码是Windows的运行时dubugger,它以最低限度运行,而不包含windows.h本身。我知道这并不能直接回答这个问题,但是为了使代码正常工作,您需要专门定义架构定义(预处理器内容(,以及<errhandlingapi.h><windef.h>。我不完全确定还有什么,所以请参考下面的例子:

我的代码:

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_IX86)
#define _X86_
#if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID)
#define _CHPE_X86_ARM64_
#endif
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_AMD64)
#define _AMD64_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_ARM)
#define _ARM_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_ARM64)
#define _ARM64_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_M68K)
#define _68K_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_MPPC)
#define _MPPC_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && defined(_M_IA64)
#if !defined(_IA64_)
#define _IA64_
#endif /* !_IA64_ */
#endif
#ifndef _MAC
#if defined(_68K_) || defined(_MPPC_)
#define _MAC
#endif
#endif
#include <string>
#include <windef.h>
#include <WinUser.h>
#include <WinNls.h>
#include <errhandlingapi.h>
#include <processthreadsapi.h>
#include <WinBase.h>
__pragma (comment(lib, "User32"));
namespace Microsoft {
void __stdcall rt_assert(const bool test, const wchar_t* FunctionName)
{
    if (test) return;
    // Retrieve the system error message for the last-error code
    unsigned __int32 ERROR_ID = GetLastError();
    void* MsgBuffer;
    LCID lcid; //language id
    GetLocaleInfoEx(L"en-US", LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (wchar_t*)&lcid, sizeof(lcid));
    //get error message and attach it to Msgbuffer
    FormatMessageW(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, ERROR_ID, lcid, (wchar_t*)&MsgBuffer, 0, NULL);
    //concatonate string to DisplayBuffer
    const std::wstring DisplayBuffer = (static_cast<std::wstring>(FunctionName) + L" failed with error " + std::to_wstring(ERROR_ID) + L": " + static_cast<const wchar_t*>(MsgBuffer)).c_str();
    // Display the error message and exit the process
    if (IsDebuggerPresent())
    {
        OutputDebugStringW(DisplayBuffer.c_str());
    }
    else
    {
        MessageBoxExW(NULL, DisplayBuffer.c_str(), L"Error", MB_ICONERROR | MB_OK, static_cast<unsigned __int16>(lcid));
    }
    ExitProcess(ERROR_ID);
}
}