C#读写EM4205/4305/4469卡复制ID卡制做FDX-B动物标签源码

本文主要是介绍C#读写EM4205/4305/4469卡复制ID卡制做FDX-B动物标签源码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        EM4305/EM4205卡是采用瑞士EM微电子公司工作频率为125kHz,具有读、写功能的非接触式RFID射频芯片,它具有功耗低、可提供多种数据传输速率和数据编码方法等特点,适合射频芯片ISO 11784/11785规范,该芯片被广泛应用于动物识别和跟踪、智能门锁、通道门禁等一卡通管理系统。

       EM4305/EM4205卡的EEPROM储存空间为512位,分为16个块,每个块32位,块1为UID块,块2为密码块,块4为配置块,块14、15为锁定标志块。可在-40℃~85℃在温度下工作。

       EM4305/EM4205卡可以修改其配置信息将其模拟成兼容EM4100的ID卡,可用于ID卡的复制。

 本示例使用的发卡器:EM4305 EM4469 ISO11784/85协议125K低频FXD-B动物标签读写发卡器-淘宝网 (taobao.com)

 函数声明

 //------------------------------------------------------------------------------------------------------------------------------------------------------//外部函数声明:让设备发出声响[DllImport("OUR_IDR.dll", EntryPoint = "idr_beep", CallingConvention = CallingConvention.StdCall)]static extern byte idr_beep(UInt32 xms);//xms单位为毫秒 //------------------------------------------------------------------------------------------------------------------------------------------------------    //读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限[DllImport("OUR_IDR.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号 //------------------------------------------------------------------------------------------------------------------------------------------------------    //只读EM4100卡号[DllImport("OUR_IDR.dll", EntryPoint = "idr_read", CallingConvention = CallingConvention.StdCall)]public static extern byte idr_read(byte[] serial);//serial返回卡号        //------------------------------------------------------------------------------------------------------------------------------------------------------    //只读卡号,只读一次EM4100卡,必须拿开卡才能再读到[DllImport("OUR_IDR.dll", EntryPoint = "idr_read_once", CallingConvention = CallingConvention.StdCall)]public static extern byte idr_read_once(byte[] serial);//serial返回卡号//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4205/4305卡写配置块[DllImport("OUR_IDR.dll", EntryPoint = "em4305_init", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_init(byte ctrlword, byte[] seria, byte[] key, byte[] configdata);//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4469/4569卡写配置块[DllImport("OUR_IDR.dll", EntryPoint = "em4469_init", CallingConvention = CallingConvention.StdCall)]public static extern byte em4469_init(byte ctrlword, byte[] seria, byte[] key, byte[] configdata);//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4205/4305/4469/4569卡读卡[DllImport("OUR_IDR.dll", EntryPoint = "em4305_read", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_read(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] readdata);//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4205/4305/4469/4569卡写卡[DllImport("OUR_IDR.dll", EntryPoint = "em4305_write", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_write(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] writedata);//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4205/4305/4469/4569卡锁定块[DllImport("OUR_IDR.dll", EntryPoint = "em4305_lock", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_lock(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag);//------------------------------------------------------------------------------------------------------------------------------------------------------//EM4205/4305/4469/4569卡改密码[DllImport("OUR_IDR.dll", EntryPoint = "em4305_changekey", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_changekey(byte ctrlword, byte[] seria, byte[] oldkey, byte[] newkey);//------------------------------------------------------------------------------------------------------------------------------------------------------//用EM4205/4305卡制作ID卡(也就是EM4100及兼容卡)[DllImport("OUR_IDR.dll", EntryPoint = "em4305_to4100", CallingConvention = CallingConvention.StdCall)]public static extern byte em4305_to4100(byte ctrlword, byte[] seria, byte[] oldkey, byte[] newkey, byte[] myuidbuf);//-----------------------------------------------------------------------------------------------------------------------------------------------------        //只读HID卡号[DllImport("OUR_IDR.dll", EntryPoint = "hid_read", CallingConvention = CallingConvention.StdCall)]public static extern byte hid_read(byte[] serial);//serial返回卡号 

读取EM4205/4305/4469/4569芯片内数据

 byte status;     //存放返回值int j;byte myctrlword = 0x00;  //控制字byte[] oldpicckey = new byte[4];  //密码byte[] mypiccserial = new byte[4];  //卡序列号byte[] mypiccdata = new byte[70];  //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据byte[] mypiccblockflag = new byte[2]; //指定读哪一块string PasswStr = textBox14.Text.Trim();string seriaStr = textBox15.Text.Trim();if (checkBox1.Checked)  //本次操作需要密码验证{myctrlword = (byte)(myctrlword + NEEDKEY);try{oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));}catch{MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox14.Select();return;}}if (checkBox2.Checked)  //仅操作指定卡号的卡{try{myctrlword = (byte)(myctrlword + NEEDSERIAL);mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));}catch{MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox15.Select();return;}}j = 0;mypiccblockflag[0] = 0x00;for (int i = 0; i < 8; i++){if (myCheckBox[i].Checked){mypiccblockflag[0] = (byte)(mypiccblockflag[0] + Math.Pow(2, i));j++;}}mypiccblockflag[1] = 0x00;for (int i = 0; i < 8; i++){if (myCheckBox[8 + i].Checked){mypiccblockflag[1] = (byte)(mypiccblockflag[1] + Math.Pow(2, i));j++;}}status = em4305_read(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, mypiccdata);if (status == 0){string blockdata = "";for (int i = 0; i < mypiccdata[1]; i++){blockdata = blockdata + mypiccdata[2 + i].ToString("X2");}textBox4.Text = blockdata;j = 0;for (int i = 0; i < 16; i++){if (myCheckBox[i].Checked){myTextBox[i].Text = blockdata.Substring(j, 8);j = j + 8;}}seriaStr = "";for (int i = 0; i < 4; i++){seriaStr = seriaStr + mypiccserial[i].ToString("X2");}idr_beep(30);MessageBox.Show("读卡成功,卡无线转输分频比:" + mypiccdata[0].ToString("D") + ",卡号:" + seriaStr, "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);}else { MessageErrInf(status); }

写数据到EM4205/4305/4469/4569芯片内

byte status;     //存放返回值int j;byte myctrlword = 0x00;               //控制字byte[] oldpicckey = new byte[4];      //密码byte[] mypiccserial = new byte[4];    //卡序列号byte[] mypiccdata = new byte[50];     //写卡数据缓冲byte[] mypiccblockflag = new byte[2]; //指定读哪一块string PasswStr = textBox14.Text.Trim();string seriaStr = textBox15.Text.Trim();int chtxt = Form1_chedkdata();if (chtxt != 100){MessageBox.Show("写卡数据输入错误,请重新输入!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);myTextBox[chtxt].Select();return;}if (checkBox1.Checked)  //本次操作需要密码验证{myctrlword = (byte)(myctrlword + NEEDKEY);try{oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));}catch{MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox14.Select();return;}}if (checkBox2.Checked)  //仅操作指定卡号的卡{try{myctrlword = (byte)(myctrlword + NEEDSERIAL);mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));}catch{MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox15.Select();return;}}if (myCheckBox[1].Checked){MessageBox.Show("块1为uid块,只能读取不可写入!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}if (myCheckBox[4].Checked){MessageBox.Show("块4为配置区,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}if (myCheckBox[14].Checked){MessageBox.Show("块14为锁定标志块,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}if (myCheckBox[15].Checked){MessageBox.Show("块15为配置区,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}j = 0;string WriteStr = "";mypiccblockflag[0] = 0x00;for (int i = 0; i < 8; i++){if (myCheckBox[i].Checked){mypiccblockflag[0] = (byte)(mypiccblockflag[0] + Math.Pow(2, i));WriteStr = WriteStr + myTextBox[i].Text;j++;}}mypiccblockflag[1] = 0x00;for (int i = 0; i < 8; i++){if (myCheckBox[8 + i].Checked){mypiccblockflag[1] = (byte)(mypiccblockflag[1] + Math.Pow(2, i));WriteStr = WriteStr + myTextBox[8 + i].Text;j++;}}for (int i = 0; i < WriteStr.Length / 2; i++){mypiccdata[i] = Convert.ToByte(Convert.ToInt32(WriteStr.Substring(i * 2, 2), 16));}status = em4305_write(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, mypiccdata);if (status == 0){seriaStr = "";for (int i = 0; i < 4; i++){seriaStr = seriaStr + mypiccserial[i].ToString("X2");}idr_beep(30);MessageBox.Show("卡号:" + seriaStr + "写卡成功!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);}else { MessageErrInf(status); }

将EM4205/4305卡制做成ID门禁卡

 byte status;     //存放返回值byte myctrlword = 0x00;  //控制字byte[] oldpicckey = new byte[4];  //密码byte[] newpicckey = new byte[4];  //新密码byte[] mypiccserial = new byte[6];  //卡序列号byte[] mypiccblockflag = new byte[2]; //指定读哪一块string PasswStr = textBox14.Text.Trim();string seriaStr = textBox15.Text.Trim();string newpassw = textBox20.Text.Trim();string newuidstr = textBox3.Text.Trim();if (checkBox1.Checked)  //本次操作需要密码验证{myctrlword = (byte)(myctrlword + NEEDKEY);try{oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));}catch{MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox14.Select();return;}}if (checkBox2.Checked)  //仅操作指定卡号的卡{try{myctrlword = (byte)(myctrlword + NEEDSERIAL);mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));}catch{MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox15.Select();return;}}if (checkBox11.Checked)  //修改卡片密码{try{myctrlword = (byte)(myctrlword + KEYENABLE);newpicckey[0] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(0, 2), 16));newpicckey[1] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(2, 2), 16));newpicckey[2] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(4, 2), 16));newpicckey[3] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(6, 2), 16));}catch{MessageBox.Show("密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBox20.Select();return;}}if (radioButton3.Checked){if (newuidstr.Length != 10 || !checkhex(newuidstr)) { MessageBox.Show("要写入的10位16进制卡号错误,请输入正确的10位16进制卡号!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }byte[] myuid = new byte[5];        //写入的新卡号try{myuid[0] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(0, 2), 16));myuid[1] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(2, 2), 16));myuid[2] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(4, 2), 16));myuid[3] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(6, 2), 16));myuid[4] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(8, 2), 16));}catch{MessageBox.Show("新卡号输入错误,请输入8位16进制数的卡号!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);textBoxuid1.Select();return;}status = em4305_to4100(myctrlword, mypiccserial, oldpicckey, newpicckey, myuid);if (status == 0){idr_beep(50);MessageBox.Show("卡号:" + System.Convert.ToString(myuid[1] * 256 * 256 * 256 + myuid[2] * 256 * 256 + myuid[3] * 256 + myuid[4]) + " 写卡成功变成ID卡!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);}else { MessageErrInf(status); }}else{MessageBox.Show("此功能暂未开发!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);}

将EM4205/4305/4469/4569卡写入FDX-B动物标签

 Int16 conutryid = Convert.ToInt16(textBox1.Text.Trim());
            Int64 SerialnumberId = Convert.ToInt64(textBox2.Text.Trim());
            Int16 Reserved = Convert.ToInt16(textBox3.Text.Trim());
            Int32 Extension = Convert.ToInt32(textBox4.Text.Trim());

            if (conutryid > 1023){
                MessageBox.Show("Country国家代码的取值范围是:0~1023!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox1.SelectionStart = 0;
                textBox1.SelectionLength = textBox1.Text.Trim().Length;
                textBox1.Select();
                return;
            }

            if (SerialnumberId > 274877906943)
            {
                MessageBox.Show("SerialNumber序列号的取值范围是:0~274877906943!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox2.SelectionStart = 0;
                textBox2.SelectionLength = textBox2.Text.Trim().Length;
                textBox2.Select();
                return;
            }

            if (Reserved > 16383)
            {
                MessageBox.Show("Reserved保留信息的取值范围是:0~16383!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox3.SelectionStart = 0;
                textBox3.SelectionLength = textBox3.Text.Trim().Length;
                textBox3.Select();
                return;
            }

            if (Extension > 16777215)
            {
                MessageBox.Show("Extension扩展信息的取值范围是:0~16777215!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox4.SelectionStart = 0;
                textBox4.SelectionLength = textBox4.Text.Trim().Length;
                textBox4.Select();
                return;
            }

            string Extensionbit = "000000000000000000000000"+Convert.ToString(Extension, 2);
            Extensionbit = Extensionbit.Substring(Extensionbit.Length - 24);

            string Reservedbit = "00000000000000" + Convert.ToString(Reserved, 2);
            Reservedbit = Reservedbit.Substring(Reservedbit.Length - 14);
            if (checkBox4.Checked) { Reservedbit = "1" + Reservedbit; } else { Reservedbit = "0" + Reservedbit; }
            if (checkBox3.Checked) { Reservedbit =  Reservedbit+"1"; } else { Reservedbit =  Reservedbit+"0"; }

            string conutrybit = "0000000000" + Convert.ToString(conutryid, 2);
            conutrybit = conutrybit.Substring(conutrybit.Length - 10);

            string Serialnumberbit = "00000000000000000000000000000000000000" + Convert.ToString(SerialnumberId, 2);
            Serialnumberbit = Serialnumberbit.Substring(Serialnumberbit.Length - 38);

            string fdxbitstr = "10000000000";       //前导码
            fdxbitstr = "1" + Serialnumberbit.Substring(30, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(22, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(14, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(6, 8) + fdxbitstr;
            fdxbitstr = "1" + conutrybit.Substring(8, 2) + Serialnumberbit.Substring(0, 6) + fdxbitstr;
            fdxbitstr = "1" + conutrybit.Substring(0, 8) + fdxbitstr;
            fdxbitstr = "1" + Reservedbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + Reservedbit.Substring(0, 8) + fdxbitstr;

            byte[] info = new byte[8]; 
            for (int i = 0; i < 8; i++)
            {
                string thisbit = fdxbitstr.Substring((i + 1) * 9 - 9, 9);
                if (thisbit.Substring(0, 1) == "1")
                {
                    info[7 - i] = (byte)Convert.ToInt16(thisbit.Substring(1, 8), 2);
                }
            }
            ushort crc16ccitt = GetCrc16Ccitt(info);
            string crcbit = "0000000000000000" + Convert.ToString(crc16ccitt, 2);
            crcbit = crcbit.Substring(crcbit.Length - 16);
            fdxbitstr = "1" + crcbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + crcbit.Substring(0, 8) + fdxbitstr;

            fdxbitstr = "1" + Extensionbit.Substring(16, 8) + fdxbitstr;
            fdxbitstr = "1" + Extensionbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + Extensionbit.Substring(0, 8) + fdxbitstr;

            byte[] writebuf = new byte[16];
            for (int i = 0; i < 16; i++)
            {
                string thisbit = fdxbitstr.Substring((i + 1) * 8 - 8, 8);
                writebuf[15 - i] = (byte)Convert.ToInt16(thisbit, 2);
            }

            byte status;                          //存放返回值
            byte myctrlword = 0x00;               //控制字
            byte[] oldpicckey = new byte[4];      //密码
            byte[] mypiccserial = new byte[4];    //卡序列号
            byte[] mypiccblockflag = new byte[2]; //指定读哪一块

            mypiccblockflag[0] = 224;
            mypiccblockflag[1] = 1;

            status = em4305_write(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, writebuf);
            if (status == 0)
            {
                if (checkBox2.Checked){
                    em4305_lock(myctrlword, mypiccserial, oldpicckey, mypiccblockflag);
                }

                string seriaStr = "";
                for (int i = 0; i < 4; i++)
                {
                    seriaStr = seriaStr + mypiccserial[i].ToString("X2");
                }
                idr_beep(30);
                MessageBox.Show("卡号:" + seriaStr + "写FDX-B协议标签成功!", "提示:", MessageBoxButtons.OK , MessageBoxIcon.Information );
                if (checkBox1.Checked)
                {
                    SerialnumberId = SerialnumberId + 1;
                    textBox2.Text = SerialnumberId.ToString("D12");
                }
            }
            else { MessageErrInf(status); }

这篇关于C#读写EM4205/4305/4469卡复制ID卡制做FDX-B动物标签源码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/310504

相关文章

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点