频道栏目
首页 > 资讯 > 其他 > 正文

windows 错误处理

17-07-25        来源:[db:作者]  
收藏   我要投稿

windows为错误处理提供了很多函数。

GetLastError

首先除了GetLastError还有一个GetLastErrorEx函数。但是现在
GetLastErrorEx和GetLastError都是相同的了。所以GetLastErrorEx的第二参数被忽略了。

GetLastError函数来让我们检查函数操作时产生的错误。它使用一种叫做“线程本地存储区”(thread-local storage)的机制将相应的错误代码和主调线程关联到一起。
通常我们使用这个函数只需要类似下面这样就可以了。

    HANDLE file = CreateFile(TEXT("C:\\test.txt"), 0, 0, nullptr, OPEN_EXISTING, 0, nullptr);

    DWORD dwResoult=GetLastError();
    switch (dwResoult) {


        //...

    }

所有的错误码都在WinError中定义着(被Windows.h包括)。当然想全部记下来是不可能的只能边学习边积累了。

为了我们调试程序的方便visual studio为我们提供了相应的工具来查看错误码。
监视窗口
我们只需要打上断点然后在监视窗口(watch)写入下面伪变量就可以参考断点处的GetLastError返回的结果了。

这里写图片描述

很方便 还会自动翻译成我们的语言。
如果想了解玩什么监视串口玩什么会显示???可以参考下面链接(要vpn的)
https://stackoverflow.com/questions/4001023/what-do-question-marks-in-visual-studio-watch-window-signify

错误查找
windows 还有一个小工具可以查看相应错误码是什么意思
这里写图片描述

这里写图片描述
但是只能输入数字,不能输入宏哦。

相应的API
当然如果想实现上面的工具的话windows 也提供了相应的api。
首先我们要用GetLastError来获得错误码(DWORD值)。然后就用到下面的函数了

//下面是UNICODE版本的
WINBASEAPI
_Success_(return != 0)
DWORD
WINAPI
FormatMessageW(
    _In_     DWORD dwFlags,
    _In_opt_ LPCVOID lpSource,
    _In_     DWORD dwMessageId,
    _In_     DWORD dwLanguageId,
    _When_((dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) != 0, _At_((LPWSTR*)lpBuffer, _Outptr_result_z_))
    _When_((dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) == 0, _Out_writes_z_(nSize))
             LPWSTR lpBuffer,
    _In_     DWORD nSize,
    _In_opt_ va_list *Arguments
    );

其实这个函数的功能是通过语言标识符来寻找相应的语言文本然后返回该文本。所以我们必须先翻译字符串,然后把并把翻译好的消息表(message table)资源嵌在.exe或者DLL模块的中。
如果希望穿件信息表可以使用Message Compiler(MC.exe)。或者上面错误查找工具的某块按钮

dwFlags
设置一些影响函数工作的标记。一般就是下面三个标记

FORMAT_MESSAGE_ALLOCATE_BUFFER | :分配一块能容下翻译完的字符串,地址就是lpBuffer参数返回的值 FORMAT_MESSAGE_FROM_SYSTEM |:获得系统定义的错误代码对应的字符串 FORMAT_MESSAGE_IGNORE_INSERTS:字符串中可以出现%号。这个就像printf函数一样我们使用%来占位,但是因为有的异常会出现%号来显示一些设备信息所。如果设置这个参数,出现%号时Arguments参数就要提供相应的占位符值了

lpSource
我们的消息表地址。如果使用系统的错误码的话设置为nullptr就行了。
dwMessageId
指出想要查找的错误码ID
dwLanguageId
使用什么语言来显示.
lpBuffer
翻译完的字符串存储的地方
nSize
如果没有设置FORMAT_MESSAGE_ALLOCATE_BUFFER值就会返回需要缓冲区的大小(和字符串处理函数一样)。如果设置了就会返回其中字符的多少个。
Arguments
为占位符提供信息

下面是我从msdn上拔下来的一个例子

#include 
#include 

void ErrorExit(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        //MAKELANGID宏会把LANG_NEUTRAL,SUBLANG_DEFAULT揉成一个数,这个数就是0表示使用系统默认的语言
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}

void main()
{
    // Generate an error

    if(!GetProcessId(NULL))
        ErrorExit(TEXT("GetProcessId"));
}

自定义错误码

当我们想使用自己的错误码时可以使用SetLastError函数来设置错误码。但是请遵守下面的规定

错误代码的不同字段位:

 

错误代码的不同字段位:

31–30

 

 

29

 

 

28

 

 

27–16

 

 

15–0

 

 

内容

 

严重性

 

Microsoft/

 

客户

保留

 

Facility

 

代码

异常代码

 

含义

 

0 =

 

成功

1 =

 

信息(提示)

2 =

 

警告

3 =

 

错误

0 = Microsoft

 

定义的代码

1 =

 

客户定义的代码

必须为

0

256个值由Microsoft保留

Microsoft/

 

客户定义的代码


相关TAG标签
上一篇:安全研究人员发现找回账号功能存在漏洞 Facebook不认账
下一篇:QQ大厅游戏 大家来找茬辅助
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站