前一段时间在学习windows api调用过程中,遇到过一些调用错误或者程序没能显示预期的结果,或者直接出现vc运行时错误。

这对新手来说是司空见惯的事,因为不太熟悉难免会出错,出错的信息如果能显示很好的关键字到网上搜索一下倒是很好的,例如

返回错误代码:2。你可以使用Visual studio套件里面的Error Lookup查询一下系统消息列表中的请求消息(system message-ta

ble resource(s) for the requested message):便可得知“系统找不到指定的文件”。有的错误根本就不显示什么错误信息,

这可难倒新手了,我也有一些c程序因此没能完成放置那里窖藏了,不懂什么时候才能碰到他。

偶然间看到网上文章讲解C#中使用托管代码来排查windows api调用,让我想起了以前下载的一段代码,也有类似的函数,于是用

工具搜索到了这段代码,本文的代码片段来自于Expat 2.1.0的win32filemap.c文件

static void
win32perror(const TCHAR *s)
{
LPVOID buf;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &buf,
,
NULL)) {
_ftprintf(stderr, _T("%s: %s"), s, buf);
fflush(stderr);
LocalFree(buf);
}
else
_ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
}

在此基础上稍稍修改了一下写了一个测试代码,如下:

以下在windows xp sp3,visual c++ 6编译通过

#include <windows.h>
#include <stdio.h>
#include <tchar.h> #define STRICT 1
#define WIN32_LEAN_AND_MEAN 1
#ifndef UNICODE
#define UNICODE
#endif static void
win32perror(const TCHAR *s)
{
LPVOID buf;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &buf,
,
NULL)) {
_ftprintf(stderr, _T("%s: %s"), s, buf);
fflush(stderr);
LocalFree(buf);
}
else
_ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
} void main(void)
{
DWORD dwLastError;
const TCHAR *wSZError = {"错误信息\0"};
GetFileAttributes("FileNotexist.txt");
dwLastError = GetLastError(); printf("操作系统返回的错误代码:%d\n",dwLastError);
win32perror(wSZError); }

程序运行结果:

以下是网络上的C#代码处理GetLastError错误代码,版权归原作者所有。

using System;
using System.ComponentModel;
// 使用平台调用技术进行互操作性之前,首先需要添加这个命名空间
using System.Runtime.InteropServices; namespace FormatMessageDotNet
{
class Program
{
// Win32 API
// DWORD WINAPI GetFileAttributes(
// _In_ LPCTSTR lpFileName
//); // 在托管代码中对非托管函数进行声明
[DllImport("Kernel32.dll",SetLastError=true,CharSet=CharSet.Unicode)]
public static extern uint GetFileAttributes(string filename); static void Main(string[] args)
{
// 试图获得一个不存在文件的属性
// 此时调用Win32函数会发生错误
GetFileAttributes("FileNotexist.txt"); // 在应用程序的Bin目录下存在一个test.txt文件,此时调用会成功
//GetFileAttributes("test.txt"); // 获得最后一次获得的错误
int lastErrorCode = Marshal.GetLastWin32Error(); // 将Win32的错误码转换为托管异常
//Win32Exception win32exception = new Win32Exception();
Win32Exception win32exception = new Win32Exception(lastErrorCode);
if (lastErrorCode != )
{
Console.WriteLine("调用Win32函数发生错误,错误信息为 : {0}", win32exception.Message);
}
else
{
Console.WriteLine("调用Win32函数成功,返回的信息为: {0}", win32exception.Message);
} Console.Read();
}
}
}

附:据说使用FormatMessage会有潜在的问题,所以以上代码绕开了这个函数。

FormatMessage函数原型:

DWORD WINAPI FormatMessage(
_In_ DWORD dwFlags,
_In_opt_ LPCVOID lpSource,
_In_ DWORD dwMessageId,
_In_ DWORD dwLanguageId,
_Out_ LPTSTR lpBuffer,
_In_ DWORD nSize,
_In_opt_ va_list *Arguments
);

其中第一个参数dwFlags开关如果用到以下参数的确会有潜在的问题。

FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100

Windows Server 2003 and Windows XP:  

If the length of the formatted message exceeds 128K bytes, then FormatMessage will not automatically fail with an error of ERROR_MORE_DATA.

也就是消息格式化超过128字节了就会出现问题,并且不会自动报告 ERROR_MORE_DATA错误,以后会单独写一篇FormatMessage函数的详细用法

FormatMessage与GetLastError配合使用,排查windows api调用过程中的错误的更多相关文章

  1. 浅议Delphi中的Windows API调用(举的两个例子分别是String和API,都不错,挺具有代表性)

    浅议Delphi中的Windows API调用http://tech.163.com/school • 2005-08-15 10:57:41 • 来源: 天极网为了能在Windows下快速开发应用程 ...

  2. Windows API 调用示例

    Ø  简介 本文主要记录 Windows API 的调用示例,因为这项技术并不常用,属于 C# 中比较孤僻或接触底层的技术,并不常用.但是有时候也可以借助他完成一些 C# 本身不能完成的功能,例如:通 ...

  3. 安装Windows 8.1过程中出现的各种问题(无损从MBR转GPT磁盘、不能定位已有分区)

    这个周末就安装了个系统,本以为一个小时就能搞定,没想到花费了将近一天. 我的机子是6G内存.500G硬盘,原装系统是Windows 7,现在想换成Windows 8.1,于是下载了64位的Window ...

  4. Windows API调用外部程序

    要在应用程序中启动其他的应用程序,有3个函数可以使用,下面我一一说说他们(我以打开D:\Program Files\zeecalls\目录下的zeecalls.exe应用程序为例): 1.Winexe ...

  5. 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当地修改源代码。 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\41c191fd\ff9345c5\App_Web_login.cshtml.65793277

    本地开发环境没问题,但是发布到服务器出现问题或则直接在IIS上修改东西就给我抛出以下错误: 未能写入输出文件"c:\Windows\Microsoft.NET\Framework64 \v4 ...

  6. 本人arcgis api for javascript中常见错误总结

    1. 2.对象不支持"replace"属性或方法 解决办法:一般在ie中执行js会报这样的错误,基本问题就是你引用了某个对象中不存在的方法,可能是这个方法本来存在而你写错了,或者调 ...

  7. 【SQL】关于存储过程调用过程中事务的点点滴滴

    1.调用两个存储过程 ---------------------------------------------------------------- -- 表[dbo].[aaa_test]中[id ...

  8. Windows 10 安装过程中,在自定义登录页面进入审核模式

    按ctrl-f3进入审核模式 https://msdn.microsoft.com/zh-cn/windows/hardware/commercialize/manufacture/desktop/b ...

  9. 百度地图API在vue-cli中路径错误的问题

    在使用百度地图的时候,需要使用自定义的icon图片,百度的案例中使用的是线上地址,但当替换为本地图片路径的时候,错误出现了 这是本地图片地址 ) // 设置覆盖物大小 ); 这里有一点需要注意,这里路 ...

随机推荐

  1. iOS开发-- RunLoop的基本概念与例子分析

    看了一下,上一篇貌似5个月前的

  2. ffmpeg relocation error

    在向imx6移植ffmpeg后,一般的编解码操作没有问题,但是当从摄像头录视频时, ffmpeg -f video4linux2 -s 640*480 -r 10 -i /dev/video0 tes ...

  3. 用:before :after 来写一些小特效

    提起:before :after首先想到的是 —— 用它来去浮动来我们来换个方式玩接下来展示三种用:before :after来实现的特效 希望能起到抛砖引玉的作用 <一>第一种就是常见的 ...

  4. php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法

    1.获取上个月第一天及最后一天.    echo date('Y-m-01', strtotime('-1 month'));    echo "<br/>";     ...

  5. python模块之configparser

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件. # 注释1 ; 注释2 [section1] # 节点 k1 = v1 # 值 k2:v2 # 值 [section ...

  6. (分享)多功能 PDF转换器v3.0版本

    转换的效果非常不错,值得使用.破解成功的截图:这个程序必须随便输入注册码注册,不然会有水印的. 这是程序主界面了 正在测试pdf转word过程,转换结果个人感觉非常不错,跟原版pdf的格式非常接近,个 ...

  7. 初识makefile

    Makefile的规则 目标 : 需要的条件 (注意冒号两边有空格) 命令 (注意前面用tab键开头) 解释一下: 1 目标可以是一个或多个,可以是Object File,也可以是执行文件,甚至可以是 ...

  8. /proc/net/tcp中各项参数说明

    /proc/net/tcp中的内容由tcp4_seq_show()函数打印,该函数中有三种打印形式,我们这里这只列出状态是TCP_SEQ_STATE_LISTENING或TCP_SEQ_STATE_E ...

  9. LSTM 分类器笔记及Theano实现

    相关讨论 http://tieba.baidu.com/p/3960350008 基于教程http://deeplearning.net/tutorial/lstm.html LSTM基本原理http ...

  10. Modified Least Square Method and Ransan Method to Fit Circle from Data

    In OpenCv, it only provide the function fitEllipse to fit Ellipse, but doesn't provide function to f ...