不同机具的通用的第二代居民身份证读写

    公安部已经大规模在全国范围内推广第二代居民身份证的换发工作,目前,许多地区二代证换发工作已经进行了很久。但是,相对应于二代证的推广,社会上许许多多的应用系统都还没有对二代证读卡开发相应的接口,为此,我写了一个通用的二代证机具读卡类,希望能对各位在各自的系统中开发这样的接口提供帮助。
    本类仅仅提供读卡的用法,写卡的方式我并没有写在里面,但是,相应的写调用我已经声明在里面,希望各位大侠能独自研究应用。
    该类接口具有如下特点:
    1、通用于目前市场上各个机具厂商的二代证读(写)机具。(想想,为不同厂商开发不同的接口确实令人头疼的,且由于接口不兼容,容易被客户骂死!
    2、自动适应串口、USB口的各种机具
    3、能读文字信息,但是,要想正确读照片,必须需要机具厂商的授权文件Termb.Lic,且授权文件必须放在C盘根目录下。(我总不能不照顾机具厂商的利益吧
    4、除了上面第三条之外,您甚至不用安装机具的驱动程序,接上二代证机具即可使用。
    
    废话少说,下面看实现方法:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection ;
using System.IO;


namespace ICCard
{
    
public class clsICCard
    
{
        
//首先,声明通用接口
        [DllImport("sdtapi.dll")]
        
public static extern int SDT_OpenPort(int iPortID);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ClosePort(int iPortID);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_PowerManagerBegin(int iPortID, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_AddSAMUser(int iPortID, string pcUserName, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_SAMLogin(int iPortID, string pcUserName, string pcPasswd, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_SAMLogout(int iPortID, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_UserManagerOK(int iPortID, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ChangeOwnPwd(int iPortID, string pcOldPasswd, string pcNewPasswd, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ChangeOtherPwd(int iPortID, string pcUserName, string pcNewPasswd, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_DeleteSAMUser(int iPortID, string pcUserName, int iIfOpen);

        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_StartFindIDCard(int iPortID, ref int pucIIN, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_SelectIDCard(int iPortID, ref int pucSN, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ReadBaseMsg(int iPortID, string pucCHMsg, ref int puiCHMsgLen, string pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ReadBaseMsgToFile(int iPortID, string fileName1, ref int puiCHMsgLen, string fileName2, ref int puiPHMsgLen, int iIfOpen);

        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_WriteAppMsg(int iPortID, ref byte pucSendData, int uiSendLen, ref byte pucRecvData, ref int puiRecvLen, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_WriteAppMsgOK(int iPortID, ref byte pucData, int uiLen, int iIfOpen);

        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_CancelWriteAppMsg(int iPortID, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ReadNewAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ReadAllAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_UsableAppMsg(int iPortID, ref byte ucByte, int iIfOpen);

        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_GetUnlockMsg(int iPortID, ref byte strMsg, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_GetSAMID(int iPortID, ref byte StrSAMID, int iIfOpen);

        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_SetMaxRFByte(int iPortID, byte ucByte, int iIfOpen);
        [DllImport(
"sdtapi.dll")]
        
public static extern int SDT_ResetSAM(int iPortID, int iIfOpen);

        [DllImport(
"WltRS.dll")]
        
public static extern int GetBmp(string file_name, int intf);

        
public delegate void De_ReadICCardComplete(clsEDZ objEDZ);
        
public event De_ReadICCardComplete ReadICCardComplete;
        
private clsEDZ objEDZ = new clsEDZ();
        
private int EdziIfOpen = 1;               //自动开关串口
        int EdziPortID;        
        
public clsICCard()
        
{

        }

        
public bool ReadICCard()
        
{           
            
bool bUsbPort = false;
            
int intOpenPortRtn = 0;
            
int rtnTemp = 0;
            
int pucIIN = 0;
            
int pucSN = 0;
            
int puiCHMsgLen = 0;
            
int puiPHMsgLen = 0;

            objEDZ 
= new clsEDZ();
            
//检测usb口的机具连接,必须先检测usb
            for (int iPort = 1001; iPort <= 1016; iPort++)
            
{
                intOpenPortRtn 
= SDT_OpenPort(iPort);
                
if (intOpenPortRtn == 144)
                
{
                    EdziPortID 
= iPort;
                    bUsbPort 
= true;
                    
break;
                }

            }

            
//检测串口的机具连接
            if (!bUsbPort)
            
{
                
for (int iPort = 1; iPort <= 2; iPort++)
                
{
                    intOpenPortRtn 
= SDT_OpenPort(iPort);
                    
if (intOpenPortRtn == 144)
                    
{
                        EdziPortID 
= iPort;
                        bUsbPort 
= false;
                        
break;
                    }

                }

            }

            
if (intOpenPortRtn != 144)
            
{                             
                MessageBox.Show(
"端口打开失败,请检测相应的端口或者重新连接读卡器!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
return false;
            }

            
//在这里,如果您想下一次不用再耗费检查端口的检查的过程,您可以把 EdziPortID 保存下来,可以保存在注册表中,也可以保存在配置文件中,我就不多写了,但是,
            
//您要考虑机具连接端口被用户改变的情况哦

            
//下面找卡
            rtnTemp = SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);
            
if (rtnTemp != 159)
            
{
                rtnTemp 
= SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);  //再找卡
                if (rtnTemp != 159)
                
{                                   
                    rtnTemp 
= SDT_ClosePort(EdziPortID);
                    MessageBox.Show(
"未放卡或者卡未放好,请重新放卡!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
return false;
                }

            }

            
//选卡
            rtnTemp = SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);
            
if (rtnTemp != 144)
            
{
                rtnTemp 
= SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);  //再选卡
                if (rtnTemp != 144)
                
{                                      
                    rtnTemp 
= SDT_ClosePort(EdziPortID);
                    MessageBox.Show(
"读卡失败!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
return false;
                }

            }

            
//注意,在这里,用户必须有应用程序当前目录的读写权限
            FileInfo objFile = new FileInfo("wz.txt");
            
if (objFile.Exists)
            
{
                objFile.Attributes 
= FileAttributes.Normal;
                objFile.Delete();
            }

            objFile 
= new FileInfo("zp.bmp");
            
if (objFile.Exists)
            
{
                objFile.Attributes 
= FileAttributes.Normal;
                objFile.Delete();
            }

            objFile 
= new FileInfo("zp.wlt");
            
if (objFile.Exists)
            
{
                objFile.Attributes 
= FileAttributes.Normal;
                objFile.Delete();
            }

            rtnTemp 
= SDT_ReadBaseMsgToFile(EdziPortID, "wz.txt"ref puiCHMsgLen, "zp.wlt"ref puiPHMsgLen, EdziIfOpen);
            
if (rtnTemp != 144)
            
{                        
                rtnTemp 
= SDT_ClosePort(EdziPortID);
                MessageBox.Show(
"读卡失败!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
return false;
            }

            
//下面解析照片,注意,如果在C盘根目录下没有机具厂商的授权文件Termb.Lic,照片解析将会失败
            if (bUsbPort)
                rtnTemp 
= GetBmp("zp.wlt"2);
            
else
                rtnTemp 
= GetBmp("zp.wlt"1);
            
switch (rtnTemp)
            
{
                
case 0:
                    MessageBox.Show(
"调用sdtapi.dll错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case 1:   //正常
                    break;
                
case -1:
                    MessageBox.Show(
"相片解码错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case -2:
                    MessageBox.Show(
"wlt文件后缀错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case -3:
                    MessageBox.Show(
"wlt文件打开错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case -4:
                    MessageBox.Show(
"wlt文件格式错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case -5:
                    MessageBox.Show(
"软件未授权!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
                
case -6:
                    MessageBox.Show(
"设备连接错误!""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
break;
            }

            rtnTemp 
= SDT_ClosePort(EdziPortID);
            FileInfo f 
= new FileInfo("wz.txt");
            FileStream fs 
= f.OpenRead();
            
byte[] bt = new byte[fs.Length];
            fs.Read(bt, 
0, (int)fs.Length);
            fs.Close();

            
string str = System.Text.UnicodeEncoding.Unicode.GetString(bt);

            objEDZ.Name 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 030).Trim();
            objEDZ.Sex_Code 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 302).Trim();
            objEDZ.NATION_Code 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 324).Trim();
            
string strBird = System.Text.UnicodeEncoding.Unicode.GetString(bt, 3616).Trim();
            objEDZ.BIRTH 
= Convert.ToDateTime(strBird.Substring(04+ "" + strBird.Substring(42+ "" + strBird.Substring(6+ "");
            objEDZ.ADDRESS 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 5270).Trim();
            objEDZ.IDC 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 12236).Trim();
            objEDZ.REGORG 
= System.Text.UnicodeEncoding.Unicode.GetString(bt, 15830).Trim();
            
string strTem = System.Text.UnicodeEncoding.Unicode.GetString(bt, 188, bt.GetLength(0- 188).Trim();
            objEDZ.STARTDATE 
= Convert.ToDateTime(strTem.Substring(04+ "" + strTem.Substring(42+ "" + strTem.Substring(62+ "");
            strTem 
= strTem.Substring(8);
            
if (strTem.Trim() != "长期")
            
{
                objEDZ.ENDDATE 
= Convert.ToDateTime(strTem.Substring(04+ "" + strTem.Substring(42+ "" + strTem.Substring(62+ "");
            }

            
else
            
{
                objEDZ.ENDDATE 
= DateTime.MaxValue;
            }

            objFile 
= new FileInfo("zp.bmp");
            
if (objFile.Exists)
            
{
                Image img 
= Image.FromFile("zp.bmp");
                objEDZ.PIC_Image
=(Image)img.Clone();
                System.IO.MemoryStream m 
= new MemoryStream();
                img.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
                objEDZ.PIC_Byte 
= m.ToArray();
                img.Dispose();
                img 
= null;
            }

            ReadICCardComplete(objEDZ);           
            
return true;
        }



    }

    
public class clsEDZ
    
{
        
private System.Collections.SortedList lstMZ = new SortedList();
        
private string _Name;   //姓名
        private string _Sex_Code;   //性别代码
        private string _Sex_CName;   //性别
        private string _IDC;      //身份证号码
        private string _NATION_Code;   //民族代码
        private string _NATION_CName;   //民族
        private DateTime _BIRTH;     //出生日期
        private string _ADDRESS;    //住址
        private string _REGORG;     //签发机关
        private DateTime _STARTDATE;    //身份证有效起始日期
        private DateTime _ENDDATE;    //身份证有效截至日期
        private string _Period_Of_Validity_Code;   //有效期限代码,许多原来系统上面为了一代证考虑,常常存在这样的字段,二代证中已经没有了
        private string _Period_Of_Validity_CName;   //有效期限
        private byte[] _PIC_Byte;    //照片二进制
        private Image _PIC_Image;   //照片

        
public clsEDZ()
        
{
            lstMZ.Add(
"01""汉族");
            lstMZ.Add(
"02""蒙古族");
            lstMZ.Add(
"03""回族");
            lstMZ.Add(
"04""藏族");
            lstMZ.Add(
"05""维吾尔族");
            lstMZ.Add(
"06""苗族");
            lstMZ.Add(
"07""彝族");
            lstMZ.Add(
"08""壮族");
            lstMZ.Add(
"09""布依族");
            lstMZ.Add(
"10""朝鲜族");
            lstMZ.Add(
"11""满族");
            lstMZ.Add(
"12""侗族");
            lstMZ.Add(
"13""瑶族");
            lstMZ.Add(
"14""白族");
            lstMZ.Add(
"15""土家族");
            lstMZ.Add(
"16""哈尼族");
            lstMZ.Add(
"17""哈萨克族");
            lstMZ.Add(
"18""傣族");
            lstMZ.Add(
"19""黎族");
            lstMZ.Add(
"20""傈僳族");
            lstMZ.Add(
"21""佤族");
            lstMZ.Add(
"22""畲族");
            lstMZ.Add(
"23""高山族");
            lstMZ.Add(
"24""拉祜族");
            lstMZ.Add(
"25""水族");
            lstMZ.Add(
"26""东乡族");
            lstMZ.Add(
"27""纳西族");
            lstMZ.Add(
"28""景颇族");
            lstMZ.Add(
"29""柯尔克孜族");
            lstMZ.Add(
"30""土族");
            lstMZ.Add(
"31""达翰尔族");
            lstMZ.Add(
"32""仫佬族");
            lstMZ.Add(
"33""羌族");
            lstMZ.Add(
"34""布朗族");
            lstMZ.Add(
"35""撒拉族");
            lstMZ.Add(
"36""毛南族");
            lstMZ.Add(
"37""仡佬族");
            lstMZ.Add(
"38""锡伯族");
            lstMZ.Add(
"39""阿昌族");
            lstMZ.Add(
"40""普米族");
            lstMZ.Add(
"41""塔吉克族");
            lstMZ.Add(
"42""怒族");
            lstMZ.Add(
"43""乌孜别克族");
            lstMZ.Add(
"44""俄罗斯族");
            lstMZ.Add(
"45""鄂温克族");
            lstMZ.Add(
"46""德昂族");
            lstMZ.Add(
"47""保安族");
            lstMZ.Add(
"48""裕固族");
            lstMZ.Add(
"49""京族");
            lstMZ.Add(
"50""塔塔尔族");
            lstMZ.Add(
"51""独龙族");
            lstMZ.Add(
"52""鄂伦春族");
            lstMZ.Add(
"53""赫哲族");
            lstMZ.Add(
"54""门巴族");
            lstMZ.Add(
"55""珞巴族");
            lstMZ.Add(
"56""基诺族");
            lstMZ.Add(
"57""其它");
            lstMZ.Add(
"98""外国人入籍");
        }


        
public string Name
        
{
            
get return _Name; }
            
set { _Name = value; }
        }

        
public string Sex_Code
        
{
            
get return _Sex_Code; }
            
set
            
{
                _Sex_Code 
= value;
                
switch (value)
                
{
                    
case "1":
                        Sex_CName 
= "";
                        
break;
                    
case "2":
                        Sex_CName 
= "";
                        
break;
                }

            }

        }

        
public string Sex_CName
        
{
            
get return _Sex_CName; }
            
set { _Sex_CName = value; }
        }

        
public string IDC
        
{
            
get return _IDC; }
            
set { _IDC = value; }
        }

        
public string NATION_Code
        
{
            
get return _NATION_Code; }
            
set
            
{
                _NATION_Code 
= value;
                
if (lstMZ.Contains(value))
                    NATION_CName 
= lstMZ[value].ToString();
            }

        }

        
public string NATION_CName
        
{
            
get return _NATION_CName; }
            
set { _NATION_CName = value; }
        }

        
public DateTime BIRTH
        
{
            
get return _BIRTH; }
            
set { _BIRTH = value; }
        }

        
public string ADDRESS
        
{
            
get return _ADDRESS; }
            
set { _ADDRESS = value; }
        }

        
public string REGORG
        
{
            
get return _REGORG; }
            
set { _REGORG = value; }
        }

        
public DateTime STARTDATE
        
{
            
get return _STARTDATE; }
            
set { _STARTDATE = value; }
        }

        
public DateTime ENDDATE
        
{
            
get return _ENDDATE; }
            
set
            
{
                _ENDDATE 
= value;
                
if (_ENDDATE == DateTime.MaxValue)
                
{
                    _Period_Of_Validity_Code 
= "3";
                    _Period_Of_Validity_CName 
= "长期";
                }

                
else
                
{
                    
if (_STARTDATE != DateTime.MinValue)
                    
{
                        
switch (value.AddDays(1).Year - _STARTDATE.Year)
                        
{
                            
case 5:
                                _Period_Of_Validity_Code 
= "4";
                                _Period_Of_Validity_CName 
= "5年";
                                
break;
                            
case 10:
                                _Period_Of_Validity_Code 
= "1";
                                _Period_Of_Validity_CName 
= "10年";
                                
break;
                            
case 20:
                                _Period_Of_Validity_Code 
= "2";
                                _Period_Of_Validity_CName 
= "20年";
                                
break;
                        }

                    }

                }


            }

        }

        
public string Period_Of_Validity_Code
        
{
            
get return _Period_Of_Validity_Code; }
            
set { _Period_Of_Validity_Code = value; }
        }

        
public string Period_Of_Validity_CName
        
{
            
get return _Period_Of_Validity_CName; }
            
set { _Period_Of_Validity_CName = value; }
        }

        
public byte[] PIC_Byte
        
{
            
get return _PIC_Byte; }
            
set { _PIC_Byte = value; }
        }

        
public Image PIC_Image
        
{
            
get return _PIC_Image; }
            
set { _PIC_Image = value; }
        }




    }

}

   类中使用到了两个dll文件(sdtapi.dll和WltRS.dll),点击这里下载!

 

posted @ 2006-01-28 12:19  南疯  阅读(18656)  评论(84编辑  收藏  举报