新中新二代身份证dll调用,报尝试读取或写入受保护的内存,这通常指示其他内存已损坏 这个错

时间:2022-08-31 08:31:59
新中新二代身份证dll调用问题:
 调用这个dll时, 到这个方法: Syn_ReadMsg(nPort, 0, ref CardMsg),就报尝试读取或写入受保护的内存。这通常指示其他内存已损坏 这个错,CardMsg是IDCardData这个结构体,结构体定义如下:
 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct IDCardData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] //结构中使用的字串,[]类似限定说明 说明此公共结构传输到非托管代码时封装定义
            public string Name; //姓名   
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
            public string Sex;   //性别
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string Nation; //名族
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string Born; //出生日期
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 72)]
            public string Address; //住址
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 38)]
            public string IDCardNo; //身份证号
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string GrantDept; //发证机关
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string UserLifeBegin; // 有效开始日期
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string UserLifeEnd;  // 有效截止日期
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 38)]
            public string reserved; // 保留
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
            public string PhotoFileName; // 照片路径
        }

   原型方法:   [DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]
        public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
  就算是新中新光盘里给的示例程序我运行都是报这个错,在论坛里找半天也没找到确切的解决方法,求高手解决
                    

26 个解决方案

#1


方法第三个参数类型改为 IntPtr
var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);
// 调用方法
var data = (IDCardData)Marshal.PtrToStructure(p, type);
Marshal.FreeHGlobal(p)

这样试试 data 有没值

#2


再不行就这样
var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);

Syn_ReadMsg( ,  , p);

var pd = p;
IDCardData data = new IDCardData();
data.Name = Marshal.PtrToStringAnsi(pd);
data.Sex = Marshal.PtrToStringAnsi(pd += 32);
data.Nation = Marshal.PtrToStringAnsi(pd += 6);
data.Born = Marshal.PtrToStringAnsi(pd += 20);
data.Address = Marshal.PtrToStringAnsi(pd += 18);
data.IDCardNo = Marshal.PtrToStringAnsi(pd += 72);
data.GrantDept = Marshal.PtrToStringAnsi(pd += 38);
data.UserLifeBegin = Marshal.PtrToStringAnsi(pd += 32);
data.UserLifeEnd = Marshal.PtrToStringAnsi(pd += 18);
data.reserved = Marshal.PtrToStringAnsi(pd += 18);
data.PhotoFileName = Marshal.PtrToStringAnsi(pd += 38);
Marshal.FreeHGlobal(p);

#3


谢谢回复,试了一下,不行,报未处理的“System.ExecutionEngineException”类型的异常出现在 未知模块 中这个错了

#4


引用 3 楼  的回复:
谢谢回复,试了一下,不行,报未处理的“System.ExecutionEngineException”类型的异常出现在 未知模块 中这个错了

这个函数的功能,是提供前面2个参数,返回一个IDCardData结构的内容吧?

#5


嗯,是的,[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]
  public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
这个是照抄sdk里的,sdk里的例子运行都是一样的错

#6


引用 5 楼  的回复:
嗯,是的,[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]
  public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
这个是照抄sdk里的,sdk里……

2楼的方法执行过了吗?
Syn_ReadMsg( ,  , p);
这行能不能执行过去?
如果不能,有没有 C/C++ 的函数和结构原型?

#7


极端点的方式
// 方法定义
[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg")]
public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, IntPtr pIDCardData);

// 调用
var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0, p);

这两行代码执行看看会不会报错

#8


 IntPtr p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0,ref p);
这样调用不会出错,就是赋值进去不了

#9


谢谢啊,二楼的方法试了可以,就是出来的乱码

#10


引用 8 楼  的回复:
IntPtr p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0,ref p);
这样调用不会出错,就是赋值进去不了

“赋值进去不了”什么意思?

#11


引用 9 楼  的回复:
谢谢啊,二楼的方法试了可以,就是出来的乱码

那好,把所有的 Marshal.PtrToStringAnsi 换成 Marshal.PtrToStringUni 试试还是不是乱码?

#12


var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg( ,  , p);
byte[] buf = new byte[32];
Marshal.Copy(p, buf, 0, buf.Length);

string str1 = Encoding.ASCII.GetString(buf);
string str2 = Encoding.Unicode.GetString(buf);
string str3 = Encoding.UTF8.GetString(buf);
string str4 = Encoding.GetEncoding("GB2312").GetString(buf);

这段代码执行下看看 str 1-4 有没哪个不是乱码

#13


嗯,谢谢啊,没报错,不过其实上没正确读取身份证的信息,而且我是这样写的
  var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);

// 调用方法
nRet = Syn_ReadMsg(0, 0,ref p);
这里返回nRet返回值是0就表示正确返回了,但是返回值不是0,表示返回的值有问题

#14


nRet = Syn_ReadMsg(0, 0,ref p);
指针不要 ref ,不然就变成双重指针了,把 ref 修饰去掉,方法定义的地方也去掉,然后运行12楼的代码

#15


不行,都是乱码,而且返回值还是2,表明没有调用成功,谢谢你了,我想想其它方法吧

#16


楼主你要贴出C++的结构定义以及函数声明大家才能进行详细的检查。你原来贴的代码从面上看应该是没什么问题的,除了这里:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,  Pack = 1)]
除非你的dll文档明确表明需要设置Pack,否则建议将其删除
还有,返回值2是什么意思?有没有可能是之前需要调用的初始化之类的函数没完成?

#17


#pragma once
#pragma pack(1)
typedef struct tagIDCardData{
char Name[32]; //姓名       
char Sex[6]; //性别
char Nation[20]; //名族
char Born[18]; //出生日期
char Address[72]; //住址
char IDCardNo[38]; //身份证号
char GrantDept[32]; //发证机关
char UserLifeBegin[18]; // 有效开始日期
char UserLifeEnd[18]; // 有效截止日期
char reserved[38]; // 保留
char PhotoFileName[255];// 照片路径
}IDCardData;
#pragma pack()
extern "C"{
//////////////////////////////////////////////////////////////////////////
// SAM端口函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_SetMaxRFByte ( int iPort, unsigned char ucByte,int bIfOpen );
int _stdcall Syn_GetCOMBaud ( int iPort, unsigned int *  puiBaudRate );
int _stdcall Syn_GetCOMBaudEx ( int iPort ); // 返回实际的波特率,0为失败
int _stdcall Syn_SetCOMBaud ( int iPort, unsigned int uiCurrBaud, unsigned int uiSetBaud );
int _stdcall Syn_OpenPort( int iPort );
int _stdcall Syn_ClosePort( int iPort );
//////////////////////////////////////////////////////////////////////////
// SAM类函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_ResetSAM ( int  iPort, int iIfOpen );
int _stdcall Syn_GetSAMStatus ( int iPort, int iIfOpen );
int _stdcall Syn_GetSAMID ( int iPort, unsigned char * pucSAMID, int iIfOpen );
int _stdcall Syn_GetSAMIDToStr ( int iPort, char * pcSAMID, int iIfOpen );
//////////////////////////////////////////////////////////////////////////
// 身份证卡类函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_StartFindIDCard ( int iPort , unsigned char * pucIIN, int iIfOpen );
int _stdcall Syn_SelectIDCard ( int iPort , unsigned char * pucSN, int iIfOpen );
int _stdcall Syn_ReadBaseMsg ( 
int iPort , 
unsigned char * pucCHMsg , 
unsigned int  * puiCHMsgLen , 
unsigned char * pucPHMsg , 
unsigned int  * puiPHMsgLen , 
int iIfOpen);
int _stdcall Syn_ReadIINSNDN ( int iPort , unsigned char * pucIINSNDN , int iIfOpen );
int _stdcall Syn_ReadBaseMsgToFile (
int  iPort,
char *  pcCHMsgFileName,
unsigned int * puiCHMsgFileLen,
char *  pcPHMsgFileName,
unsigned int  * puiPHMsgFileLen,
int iIfOpen
);
int _stdcall Syn_ReadIINSNDNToASCII ( int iPort , unsigned char * pucIINSNDN , int iIfOpen );
int _stdcall Syn_ReadNewAppMsg(int iPort , unsigned char * pucAppMsg , unsigned int * puiAppMsgLen , int iIfOpen);
int _stdcall Syn_GetBmp( int iPort , char * Wlt_File );

int _stdcall Syn_ReadMsg( int iPort,int iIfOpen,IDCardData *pIDCardData );
int _stdcall Syn_FindReader();
int _stdcall Syn_BmpToJpeg( char * cBmpName , char * cJpegName);
int _stdcall Syn_GetPhotoBmp(char * cBmpName);
//////////////////////////////////////////////////////////////////////////
// 设置附加功能函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_SetPhotoPath( int iOption , char * cPhotoPath );
int _stdcall Syn_SetPhotoType( int iType );
int _stdcall Syn_SetPhotoName( int iType );
int _stdcall Syn_SetSexType( int iType );
int _stdcall Syn_SetNationType( int iType );
int _stdcall Syn_SetBornType( int iType );
int _stdcall Syn_SetUserLifeBType( int iType );
int _stdcall Syn_SetUserLifeEType( int iType ,int iOption);
}
c++里的原型应该是这个

#18


引用 15 楼  的回复:
不行,都是乱码,而且返回值还是2,表明没有调用成功,谢谢你了,我想想其它方法吧

先把参数定义为 IntPtr 型是不想方法执行被可能错误的结构所影响,因为就算传对了结构,也是一片内存区域,与这无异,而传错了,方法就无法返回了。等把方法的其他部分调整好,能返回正确值了,再将类型设置为结构,解析结构内容。

#19


嗯,也试了一下,之前返回2是因为第一个参数传的端口传错了,传入正确的端口以后,还是报错,
尝试读取或写入受保护的内存。这通常指示其他内存已损坏 这个错,
调用方法:
var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(nport, 0, p);
nport为读写器的端口,这里赋值以后是1001

#20


表示关注,另外你有没有试过其它已有程序读取,确认读卡器已经身份证本身都可以正常被读取,这种和外设有个的操作,先要排除外设问题才行。

#21


新中新的有个示例。你问他们官方要一下。

我刚上传的好象新中新的。http://download.csdn.net/detail/zanfeng/4363831

http://download.csdn.net/detail/zanfeng/4363831
他们给的例子。是一个控件使用很简单了。

#22


谢谢大家,我是新中新光盘里给的例子运行都报错,而且是公司的笔记本,家里的电脑都报一样的错

#23


明天就要交东西了,结贴算了,周一去用同事的电脑试试,谢谢大家

#24


可能与版本有关系。新中新的现在出了好几种设备。相同设备也不同版本了。我也遇到一回改为他们的控件方式。

#25


sdk中有一个license.dat文件,把这个文件copy到系统盘根目录下就OK了!我试过的!

#26


25楼正解,如果是vista以上系统,调试中可能也会出现此错误,必须编译后用管理员模式运行。默认的普通是禁止访问系统根目录文件的。

#1


方法第三个参数类型改为 IntPtr
var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);
// 调用方法
var data = (IDCardData)Marshal.PtrToStructure(p, type);
Marshal.FreeHGlobal(p)

这样试试 data 有没值

#2


再不行就这样
var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);

Syn_ReadMsg( ,  , p);

var pd = p;
IDCardData data = new IDCardData();
data.Name = Marshal.PtrToStringAnsi(pd);
data.Sex = Marshal.PtrToStringAnsi(pd += 32);
data.Nation = Marshal.PtrToStringAnsi(pd += 6);
data.Born = Marshal.PtrToStringAnsi(pd += 20);
data.Address = Marshal.PtrToStringAnsi(pd += 18);
data.IDCardNo = Marshal.PtrToStringAnsi(pd += 72);
data.GrantDept = Marshal.PtrToStringAnsi(pd += 38);
data.UserLifeBegin = Marshal.PtrToStringAnsi(pd += 32);
data.UserLifeEnd = Marshal.PtrToStringAnsi(pd += 18);
data.reserved = Marshal.PtrToStringAnsi(pd += 18);
data.PhotoFileName = Marshal.PtrToStringAnsi(pd += 38);
Marshal.FreeHGlobal(p);

#3


谢谢回复,试了一下,不行,报未处理的“System.ExecutionEngineException”类型的异常出现在 未知模块 中这个错了

#4


引用 3 楼  的回复:
谢谢回复,试了一下,不行,报未处理的“System.ExecutionEngineException”类型的异常出现在 未知模块 中这个错了

这个函数的功能,是提供前面2个参数,返回一个IDCardData结构的内容吧?

#5


嗯,是的,[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]
  public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
这个是照抄sdk里的,sdk里的例子运行都是一样的错

#6


引用 5 楼  的回复:
嗯,是的,[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]
  public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
这个是照抄sdk里的,sdk里……

2楼的方法执行过了吗?
Syn_ReadMsg( ,  , p);
这行能不能执行过去?
如果不能,有没有 C/C++ 的函数和结构原型?

#7


极端点的方式
// 方法定义
[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg")]
public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, IntPtr pIDCardData);

// 调用
var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0, p);

这两行代码执行看看会不会报错

#8


 IntPtr p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0,ref p);
这样调用不会出错,就是赋值进去不了

#9


谢谢啊,二楼的方法试了可以,就是出来的乱码

#10


引用 8 楼  的回复:
IntPtr p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(0, 0,ref p);
这样调用不会出错,就是赋值进去不了

“赋值进去不了”什么意思?

#11


引用 9 楼  的回复:
谢谢啊,二楼的方法试了可以,就是出来的乱码

那好,把所有的 Marshal.PtrToStringAnsi 换成 Marshal.PtrToStringUni 试试还是不是乱码?

#12


var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg( ,  , p);
byte[] buf = new byte[32];
Marshal.Copy(p, buf, 0, buf.Length);

string str1 = Encoding.ASCII.GetString(buf);
string str2 = Encoding.Unicode.GetString(buf);
string str3 = Encoding.UTF8.GetString(buf);
string str4 = Encoding.GetEncoding("GB2312").GetString(buf);

这段代码执行下看看 str 1-4 有没哪个不是乱码

#13


嗯,谢谢啊,没报错,不过其实上没正确读取身份证的信息,而且我是这样写的
  var type = typeof(IDCardData);
var size = Marshal.SizeOf(type);
var p = Marshal.AllocHGlobal(size);

// 调用方法
nRet = Syn_ReadMsg(0, 0,ref p);
这里返回nRet返回值是0就表示正确返回了,但是返回值不是0,表示返回的值有问题

#14


nRet = Syn_ReadMsg(0, 0,ref p);
指针不要 ref ,不然就变成双重指针了,把 ref 修饰去掉,方法定义的地方也去掉,然后运行12楼的代码

#15


不行,都是乱码,而且返回值还是2,表明没有调用成功,谢谢你了,我想想其它方法吧

#16


楼主你要贴出C++的结构定义以及函数声明大家才能进行详细的检查。你原来贴的代码从面上看应该是没什么问题的,除了这里:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,  Pack = 1)]
除非你的dll文档明确表明需要设置Pack,否则建议将其删除
还有,返回值2是什么意思?有没有可能是之前需要调用的初始化之类的函数没完成?

#17


#pragma once
#pragma pack(1)
typedef struct tagIDCardData{
char Name[32]; //姓名       
char Sex[6]; //性别
char Nation[20]; //名族
char Born[18]; //出生日期
char Address[72]; //住址
char IDCardNo[38]; //身份证号
char GrantDept[32]; //发证机关
char UserLifeBegin[18]; // 有效开始日期
char UserLifeEnd[18]; // 有效截止日期
char reserved[38]; // 保留
char PhotoFileName[255];// 照片路径
}IDCardData;
#pragma pack()
extern "C"{
//////////////////////////////////////////////////////////////////////////
// SAM端口函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_SetMaxRFByte ( int iPort, unsigned char ucByte,int bIfOpen );
int _stdcall Syn_GetCOMBaud ( int iPort, unsigned int *  puiBaudRate );
int _stdcall Syn_GetCOMBaudEx ( int iPort ); // 返回实际的波特率,0为失败
int _stdcall Syn_SetCOMBaud ( int iPort, unsigned int uiCurrBaud, unsigned int uiSetBaud );
int _stdcall Syn_OpenPort( int iPort );
int _stdcall Syn_ClosePort( int iPort );
//////////////////////////////////////////////////////////////////////////
// SAM类函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_ResetSAM ( int  iPort, int iIfOpen );
int _stdcall Syn_GetSAMStatus ( int iPort, int iIfOpen );
int _stdcall Syn_GetSAMID ( int iPort, unsigned char * pucSAMID, int iIfOpen );
int _stdcall Syn_GetSAMIDToStr ( int iPort, char * pcSAMID, int iIfOpen );
//////////////////////////////////////////////////////////////////////////
// 身份证卡类函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_StartFindIDCard ( int iPort , unsigned char * pucIIN, int iIfOpen );
int _stdcall Syn_SelectIDCard ( int iPort , unsigned char * pucSN, int iIfOpen );
int _stdcall Syn_ReadBaseMsg ( 
int iPort , 
unsigned char * pucCHMsg , 
unsigned int  * puiCHMsgLen , 
unsigned char * pucPHMsg , 
unsigned int  * puiPHMsgLen , 
int iIfOpen);
int _stdcall Syn_ReadIINSNDN ( int iPort , unsigned char * pucIINSNDN , int iIfOpen );
int _stdcall Syn_ReadBaseMsgToFile (
int  iPort,
char *  pcCHMsgFileName,
unsigned int * puiCHMsgFileLen,
char *  pcPHMsgFileName,
unsigned int  * puiPHMsgFileLen,
int iIfOpen
);
int _stdcall Syn_ReadIINSNDNToASCII ( int iPort , unsigned char * pucIINSNDN , int iIfOpen );
int _stdcall Syn_ReadNewAppMsg(int iPort , unsigned char * pucAppMsg , unsigned int * puiAppMsgLen , int iIfOpen);
int _stdcall Syn_GetBmp( int iPort , char * Wlt_File );

int _stdcall Syn_ReadMsg( int iPort,int iIfOpen,IDCardData *pIDCardData );
int _stdcall Syn_FindReader();
int _stdcall Syn_BmpToJpeg( char * cBmpName , char * cJpegName);
int _stdcall Syn_GetPhotoBmp(char * cBmpName);
//////////////////////////////////////////////////////////////////////////
// 设置附加功能函数
//
//////////////////////////////////////////////////////////////////////////
int _stdcall Syn_SetPhotoPath( int iOption , char * cPhotoPath );
int _stdcall Syn_SetPhotoType( int iType );
int _stdcall Syn_SetPhotoName( int iType );
int _stdcall Syn_SetSexType( int iType );
int _stdcall Syn_SetNationType( int iType );
int _stdcall Syn_SetBornType( int iType );
int _stdcall Syn_SetUserLifeBType( int iType );
int _stdcall Syn_SetUserLifeEType( int iType ,int iOption);
}
c++里的原型应该是这个

#18


引用 15 楼  的回复:
不行,都是乱码,而且返回值还是2,表明没有调用成功,谢谢你了,我想想其它方法吧

先把参数定义为 IntPtr 型是不想方法执行被可能错误的结构所影响,因为就算传对了结构,也是一片内存区域,与这无异,而传错了,方法就无法返回了。等把方法的其他部分调整好,能返回正确值了,再将类型设置为结构,解析结构内容。

#19


嗯,也试了一下,之前返回2是因为第一个参数传的端口传错了,传入正确的端口以后,还是报错,
尝试读取或写入受保护的内存。这通常指示其他内存已损坏 这个错,
调用方法:
var p = Marshal.AllocHGlobal(10240);
var result = Syn_ReadMsg(nport, 0, p);
nport为读写器的端口,这里赋值以后是1001

#20


表示关注,另外你有没有试过其它已有程序读取,确认读卡器已经身份证本身都可以正常被读取,这种和外设有个的操作,先要排除外设问题才行。

#21


新中新的有个示例。你问他们官方要一下。

我刚上传的好象新中新的。http://download.csdn.net/detail/zanfeng/4363831

http://download.csdn.net/detail/zanfeng/4363831
他们给的例子。是一个控件使用很简单了。

#22


谢谢大家,我是新中新光盘里给的例子运行都报错,而且是公司的笔记本,家里的电脑都报一样的错

#23


明天就要交东西了,结贴算了,周一去用同事的电脑试试,谢谢大家

#24


可能与版本有关系。新中新的现在出了好几种设备。相同设备也不同版本了。我也遇到一回改为他们的控件方式。

#25


sdk中有一个license.dat文件,把这个文件copy到系统盘根目录下就OK了!我试过的!

#26


25楼正解,如果是vista以上系统,调试中可能也会出现此错误,必须编译后用管理员模式运行。默认的普通是禁止访问系统根目录文件的。