1。什么是SQLHelper?

SqlHelper是基于.NET Framework开发的数据库操作组件,主要通过封装ADO.NET对象(如SqlConnection、SqlCommand)简化数据库访问流程。该组件通过静态方法提供统一的数据访问模式,支持传入连接字符串和SQL参数快速执行数据库交互。


解读SQLHelper:
https://blog.csdn.net/weixin_66547608/article/details/150936831

原版下载:
https://www.cnblogs.com/dnawo/archive/2012/08/14/2638401.html

中文注释版下载:
https://www.cnblogs.com/gb2013/archive/2009/12/20/1628013.html


2。N层框架?


N层框架核心层:


Model层,模型层,实体层,主要负责对数据库中的对象(表,视图,存储过程等)做映射,把数据库中的对象转化成C#语言中的类对象,将来在C#项目中使用类对象,就相当于使用了数据库中的对象。  映射:ORM  对象关系映射   Object Relation Mapping

IDAL接口层,负责抽象DAL层中的共性。将来不同的数据库都可以实现这个共性,达到一个项目使用多个数据库的目的,可以方便的切换数据库。

DAL数据访问层,主要负责和数据库交互。SQLServerDAL负责和SQLServer数据库交互,OracleDAL负责和Oracle数据库交互。

DALFactory抽象工厂层,主要负责DAL的创建(实例化)。根据各种数据库的DAL都必须实现某种接口IDAL,才可以让抽象工厂层根据配置文件创建不同数据库实现的DAL。有了抽象工厂层,可以让BLL不再强依赖DAL,达到解耦的目的。

BLL业务逻辑层,主要负责对数据库交互(即DAL层)封装,以及对UI校验逻辑的封装。UI层将来直接使用BLL层,UI不使用DAL。

UI层:WindowForm项目来实现UI层,UI层依赖BLL,Model,DAL

以下两层是工具层,不是核心层:
Common层,公共层,一般把一个“小工具”封装到这一层中,供其他层使用。也可以称为“助手层”

DBUtility层,数据库工具层


N层框架依赖关系:


Model不依赖任何层
IDAL依赖Model
SQLServerDAL依赖IDAL,Model,Utility
DALFactory依赖Utility
BLL依赖IDAL,DALFactory,Model
UI依赖BLL,Model,SQLServerDAL


3。回顾一下ADO.NET六大对象?


a. SqlConnection

b. SqlCommand  对象重要的属性:
CommandType
CommandText
Parameters
SqlCommand  重要的方法:
ExecuteNoQuery()
ExecuteReader()
ExecuteScalar()

c. SqlDataReader

d. SqlDataAdapter

e. DataSet

f. SqlParameter

一、连接式操作核心(全程依赖数据库连接)

1. Connection 数据库连接对象

✅ 一句话定位:所有数据库操作的基础,负责建立应用和数据库的物理连接
✅ 核心重点:

  • 核心配置:ConnectionString连接字符串,存储数据库地址、账号、库名、连接超时等信息
  • 关键操作:Open()打开连接、Close()关闭连接
  • 必守规则:连接是稀缺资源,用完必须及时释放,推荐用using语法自动释放(ADO.NET默认启用连接池复用连接,不主动释放会导致资源耗尽)

2. Command SQL 命令执行对象

✅ 一句话定位:向数据库发送 SQL 语句、存储过程的载体
✅ 核心重点:

  • 核心配置:CommandText(要执行的 SQL / 存储过程名)、Parameters(参数集合,用于参数化查询,是防范 SQL 注入的核心手段)
  • 三个执行方法对应完全不同的场景:
    • ExecuteNonQuery():执行增删改操作,返回受影响的行数
    • ExecuteScalar():执行查询,返回结果集第一行第一列的值,适合查COUNTSUM这类单值结果
    • ExecuteReader():执行查询,返回数据流对象DataReader

3. DataReader 数据读取器

✅ 一句话定位:高性能、低内存占用的只读数据遍历工具
✅ 核心重点:

  • 特点:全程需要保持连接打开,只能按顺序向前遍历、只读不能改,内存开销极小,读取速度极快
  • 适用场景:只需要快速遍历查询结果、不需要修改数据的场景,比如查询大量列表数据
  • 注意:用完必须立即关闭,否则会一直占用连接

4. Transaction 事务对象

✅ 一句话定位:保证多步数据库操作的原子性(要么全部成功,要么全部回滚)
✅ 核心重点:

  • 使用流程:Connection.BeginTransaction()开启事务 → 所有待执行的Command都绑定到该事务 → 所有操作成功调用Commit()提交 → 出现异常调用Rollback()回滚所有操作
  • 适用场景:转账、订单生成这类需要多步操作强一致的场景

二、离线式操作核心(可断开数据库连接操作内存数据)

5. DataAdapter 数据适配器

✅ 一句话定位:连接数据库和离线数据集的「桥梁」
✅ 核心重点:

  • 内置 4 个 Command 对应 4 类操作:SelectCommand(查询)、InsertCommand(新增)、UpdateCommand(修改)、DeleteCommand(删除)
  • 两个核心方法:
    • Fill():自动管理连接生命周期,把数据库数据拉取填充到DataSet/DataTable,不需要手动打开 / 关闭连接
    • Update():把离线数据集里的修改批量同步回数据库
  • 效率技巧:单表操作场景可以搭配CommandBuilder,自动生成增删改 SQL,不需要手动编写

6. DataSet 数据集

✅ 一句话定位:内存中的「微型数据库」,完全离线独立运行
✅ 核心重点:

  • 特点:不需要依赖数据库连接,内部可以存储多张DataTable(数据表),支持定义表间关联、主键、约束,支持对数据做增删改查、过滤、排序,还可以和 XML 互相转换
  • 适用场景:需要离线修改数据、多表关联操作、跨层传输数据的场景
  • 轻量化替代:如果只操作单张表,可直接用更轻量的DataTable

4。SQLHelper助手?


有两个版本:官方,方法少,代码量少
开发者扩展的,带中文注释,重载方法多。虽然多,主要方法就四个重要方法:
a. ExectuteDataset()返回一个DataSet()     FillDataset()没有返回值,但可以填充DataSet参数。
b. ExecuteNoQuery()返回影响的行数
c. ExectuteReader()返回DataReader,循环获取数据
d. ExecuteScalar()返回第一行第一列的值

5。Sql分页方案?


https://blog.csdn.net/zls365365/article/details/128739389
https://cloud.tencent.com/developer/article/2037986
https://blog.csdn.net/weixin_37610397/article/details/80892426

推荐两种方案:
sqlserver2012至今 推荐使用offset/fetch next
sqlserver2005至sqlserver2012 之间推荐使用row_number方案

其他方案涉及嵌套查询,性能低,不推荐。

1.分页方案1

--分页方案1:最推荐方案,是目前最好的方案。
select * from College
order by CollegeId 
offset 0 rows fetch next 2 rows only;


--offset偏移量
--偏移量公式:(page-1)*pageSize

declare @page int  -- 页码,第几页
declare @pageSize int --每页显示几条数据

set @page=4
set @pageSize=2

select * from College
order by CollegeId 
offset (@page-1)*@pageSize rows 
fetch next @pageSize rows only;

2.分页方案2

declare @page int
declare @pageSize int
declare @startIndex int;
declare @endIndex int;

set @page=1
set @pageSize=2

/*
	startindex = (page - 1) * pageSize + 1
	endindex = page*pageSize
	page=1, startindex=1, endindex=2
	page=2, startindex=3, endindex=4
	page=3, startindex=5, endindex=6
	page=4, startindex=7, endindex=8

	startIndex = pageSize*page-1
	endindex = pageSize*page
*/

set @startIndex = (@page-1)*@pageSize+1
set @endIndex = @page*@pageSize

;with MyData (RowNum, CollegeId, CollegeName, Status, CreateUserId, CreateTime, LastUpdateUserId, LastUpdateTime)
as
(
	select 
	row_number() over(order by CollegeId asc) as RowNum,* 
	from College
)
select * from MyData 
where RowNum >=@startIndex and RowNum<=@endIndex

3.分页方案2的旧写法

declare @page int
declare @pageSize int
declare @startIndex int;
declare @endIndex int;

set @page=1
set @pageSize=2

/*
	startindex = (page - 1) * pageSize + 1
	endindex = page*pageSize
	page=1, startindex=1, endindex=4
	page=2, startindex=5, endindex=8
	

	startIndex = pageSize*page-1
	endindex = pageSize*page
*/

set @startIndex = (@page - 1) * @pageSize + 1
set @endIndex = @page*@pageSize

select * from 
(
	select 
	row_number() over(order by CollegeId asc) as RowNum,* 
	from College
) as tmp
where RowNum >=@startIndex
and RowNum<=@endIndex

6。C# 加密及解密?

加密算法

根据当前密码学领域的通用分类标准,加密算法主要分为三大类:对称加密算法非对称加密算法哈希算法(散列函数)。这三类算法在原理、密钥使用方式和应用场景上有着本质区别,共同构成了现代信息安全的基础。C#中常用的加密算法DES,AES,RSA,MD5这几种。‌‌

  1. 对称加密算法

对称加密算法,也称为私钥加密算法,其核心特征是加密和解密使用同一把密钥(或可相互推导的等价密钥)。这类算法的优点是加解密速度快、效率高,适合对大量数据进行加密处理。‌‌

‌主要特点‌:算法公开,计算量小,加密效率高。其安全性完全依赖于密钥的保密性,密钥需要在通信双方之间安全共享,这是其主要挑战。‌‌‌

‌常见算法‌:

‌DES (Data Encryption Standard)‌:早期的数据加密标准,使用56位密钥,因密钥过短已被认为不安全,逐渐被淘汰。‌‌‌‌

‌3DES (Triple DES)‌:DES的增强版,对数据块进行三次加密,安全性提高,但处理速度较慢。‌‌‌‌

‌AES (Advanced Encryption Standard)‌:目前最流行、最安全的对称加密标准,用于替代DES。它支持128、192和256位等多种密钥长度,在软硬件上都能快速实现。‌‌

百科

其他算法还包括IDEA、RC系列以及中国的‌SM4‌国家标准算法等。

‌‌

  1. 非对称加密算法

非对称加密算法,也称为公钥加密算法,它使用一对数学上关联的密钥:公钥和私钥。公钥可以公开,用于加密或验证签名;私钥必须保密,用于解密或生成签名。‌非对称加密解决了对称加密中密钥分发难的问题,但加解密速度通常比对称加密慢得多。‌‌‌

‌主要特点‌:无需事先共享密钥,解决了密钥分发问题,常用于数字签名、身份认证和密钥协商。其安全性基于复杂的数学难题(如大整数分解、椭圆曲线离散对数)。‌‌‌‌

‌常见算法‌:

‌RSA‌:最经典和广泛应用的非对称算法,安全性基于大整数质因数分解的难度。可用于加密和数字签名。‌‌

‌ECC (椭圆曲线密码学)‌:相比RSA,在相同安全强度下所需密钥长度更短、处理速度更快、存储空间更小,特别适用于移动设备等资源受限环境。‌‌

‌DSA (数字签名算法)‌:主要用于数字签名,不用于加密。‌‌

中国的‌SM2‌椭圆曲线公钥密码算法也是重要的非对称加密标准。

‌‌

  1. 哈希算法  Hash

哈希算法,又称散列函数或摘要算法,是一种单向加密算法。它将任意长度的输入数据映射为固定长度的输出(哈希值),且过程不可逆。‌哈希算法主要用于验证数据的完整性,确保信息在传输过程中未被篡改。‌‌‌

‌主要特点‌:单向性(不可逆)、抗碰撞性(难以找到两个不同输入产生相同输出)、雪崩效应(输入微小改变导致输出巨大差异)。它不需要密钥(但存在带密钥的变种如HMAC)。‌‌‌

‌主要用途‌:密码存储、数字签名、数据完整性校验。‌‌‌

‌常见算法‌:

‌MD5‌:产生128位哈希值,但已被证实存在碰撞漏洞,不再推荐用于安全目的。‌‌

百科‌

‌SHA系列‌:如SHA-1、SHA-256等。SHA-1也已发现弱点,目前‌SHA-256‌等更安全的版本被广泛推荐使用。‌‌


加密算法主要分为三大类:对称加密算法、非对称加密算法和哈希算法(散列函数)。
C#中常用的加密算法:DES,AES,RSA,MD5这几种。

对称加密算法,也称为私钥加密算法,其核心特征是加密和解密使用同一把密钥。 DES,AES
非对称加密算法,也称为公钥加密算法,它使用一对数学上关联的密钥:公钥和私钥。RAS
哈希算法,又称散列函数或摘要算法,是一种单向加密算法。MD5

https://blog.csdn.net/weixin_42113456/article/details/151583486
https://www.cnblogs.com/suqq/p/13150546.html
https://blog.51cto.com/u_11566683/6045656?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utility.Encrypt;

namespace UI
{
    public partial class Form2 : Form
    {
        string key1 = "12345678"; // 必须是8字节
        string key2 = "12345678901234567890123456789012"; // 必须是32字节
        RSA rsa = RSA.Create();
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // DES加密
            if (radioButton1.Checked)
            {
                textBox2.Text = DESHelper.Encrypt(textBox1.Text, key1);
            }
            // AES加密
            if (radioButton2.Checked)
            {
                textBox2.Text = AESHelper.Encrypt(textBox1.Text, key2);
            }
            // RSA加密
            if (radioButton3.Checked)
            {
                // 产生加密使用的公钥
                string publicKey = rsa.ToXmlString(false); // false 表示仅导出公钥
                textBox2.Text = RSAHelper.Encrypt(textBox1.Text, publicKey);
            }
            // MD5加密
            if (radioButton4.Checked)
            {
                textBox2.Text = MD5Helper.Encrypt(textBox1.Text);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // DES解密
            if (radioButton1.Checked)
            {
                textBox1.Text = DESHelper.Decrypt(textBox2.Text, key1);
            }
            // AES解密
            if (radioButton2.Checked)
            {
                textBox1.Text = AESHelper.Decrypt(textBox2.Text, key2);
            }
            // RSA解密
            if (radioButton3.Checked)
            {
                // 产生解密使用的私钥
                string privateKey = rsa.ToXmlString(true); // true 表示导出私钥
                textBox1.Text = RSAHelper.Decrypt(textBox2.Text, privateKey);
            }
            // MD5解密
            if (radioButton4.Checked)
            {
                MessageBox.Show("MD5无法解密,只能暴力破解!");
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string mw = MD5Helper.Encrypt(textBox3.Text);
            if (mw == textBox2.Text)
            {
                MessageBox.Show("猜对了!");
            }
            else
            {
                MessageBox.Show("猜错了!");
            }
        }
    }
}

using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class AESHelper
    {
        private static string iv = "1234567890123456"; // 必须是16字节
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string key)
        {
            // 创建AES对象(也是加密服务提供者)
            using (Aes aes = Aes.Create())
            {
                // 给加密服务提供者设置一些参数
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                // 创建加密者
                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
                byte[] encryptedBytes = encryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);

                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string key)
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                byte[] cipherBytes = Convert.FromBase64String(cipherText);
                byte[] decryptedBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}
using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    /// <summary>
    /// DES加密解密
    /// </summary>
    public static class DESHelper
    {
        private static string iv = "abcd6666"; // 初始化向量(8字节,必须是8个字节)
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">纯文本(明文)</param>
        /// <param name="key">密钥(8字节)</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string key)
        {
            // DESCryptoServiceProvider类是 DES加密服务的提供者
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                // 给加密服务提供密钥和初始化向量
                des.Key = Encoding.UTF8.GetBytes(key);
                des.IV = Encoding.UTF8.GetBytes(iv);
                // 加密者
                ICryptoTransform encryptor = des.CreateEncryptor(des.Key, des.IV);
                // 先把明文编码,转换UTF8编码的字节数组。
                byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                // TransformFinalBlock()把明文的字节数组转换成密文的字节数组 。
                byte[] encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
                // 把密文字节数组转换成Base64字符串
                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="key">密钥(8字节)</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string key)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = Encoding.UTF8.GetBytes(key);
                des.IV = Encoding.UTF8.GetBytes(iv);

                ICryptoTransform decryptor = des.CreateDecryptor(des.Key, des.IV);

                byte[] cipherBytes = Convert.FromBase64String(cipherText);
                byte[] decryptedBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class MD5Helper
    {
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <returns>密码</returns>
        public static string Encrypt(string plainText)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
                byte[] hashBytes = md5.ComputeHash(inputBytes);
                StringBuilder sb = new StringBuilder();
                foreach (byte b in hashBytes)
                {
                    sb.Append(b.ToString("x2")); // 转换为16进制字符串
                }
                return sb.ToString();
            }
        }
    }
}
using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class RSAHelper
    {
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="publicKey">公钥</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string publicKey)
        {
            // 把明文转换成字节数组
            byte[] data = Encoding.UTF8.GetBytes(plainText);
            // 创建RSA对象(加密服务提供者)
            using (RSA rsa = RSA.Create())
            {
                // 从XML中导入密钥
                rsa.FromXmlString(publicKey);
                // 加密,产生密文字节数组
                byte[] encryptedBytes = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
                // 把密文字节数组转换成Base64字符串
                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 密文解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="privateKey">私钥</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string privateKey)
        {
            // 把密文转换字节数组。
            byte[] data = Convert.FromBase64String(cipherText);
            using (RSA rsa = RSA.Create())
            {
                rsa.FromXmlString(privateKey);
                // 解密,产生明文字节数组
                byte[] decryptedBytes = rsa.Decrypt(data, RSAEncryptionPadding.Pkcs1);
                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}

7。INI文件读写

INI文件

INI文件(Initialization File)是一种结构简单、人类可读的纯文本配置格式,由节([section])、键值对(key=value)和注释(;或#开头)组成,当前仍广泛用于轻量级、非复杂场景的配置管理

INI文件详细了解:https://baike.baidu.com/item/INI/9212321‌‌

  1. 应用场景:

‌应用程序本地配置‌:如游戏设置(分辨率、语言)、桌面软件偏好(主题、路径)、工具链参数(端口、超时、日志级别),便于手动修改且无需注册表或复杂解析。

‌嵌入式与资源受限系统‌:因文件体积小、解析开销低,常用于IoT设备、单片机固件(如使用minIni库)存储运行参数,避免使用数据库或JSON/YAML的解析负担。

‌遗留系统维护与兼容性‌:Windows早期系统(win.ini、system.ini)及部分老式企业软件仍依赖INI;Qt、Git(如.gitconfig可设为INI格式)等跨平台工具也支持INI作为可选配置格式。

‌开发/测试环境隔离‌:通过不同INI文件(如dev.ini、prod.ini)管理数据库连接、API地址等,避免代码硬编码,支持快速切换环境。

‌系统级个性化设置‌:Windows中desktop.ini用于自定义文件夹图标/背景;某些安装程序或启动加载器(如旧版Windows的boot.ini)曾用其引导配置(现代系统多被BCD取代)。‌‌

虽已被XML、JSON、YAML等在复杂结构、类型安全、嵌套支持上逐步替代,但‌INI仍因其简洁性、易编辑性、跨平台文本兼容性,在轻量级、静态、非敏感配置场景保持实用价值‌。不适用于密钥存储(明文风险)、动态数据、多层级嵌套或需模式校验的场

  1. 在上位机行业中应用场景:

INI 文件在上位机中主要用于存储轻量级、结构化配置信息,便于人工可读、跨机器部署和快速初始化。‌‌

‌通信参数配置‌:如串口(波特率、数据位、停止位)、TCP/IP(IP、端口)、Modbus地址等,启动时自动加载,避免重复设置。

‌人机界面(HMI)偏好‌:保存窗口位置、主题颜色、字体大小、报警阈值等,实现“上次状态恢复”。

‌多设备/多产线适配‌:通过不同 INI 文件(如 Line1.ini、Line2.ini)切换控制策略,无需重新编译软件。

‌快捷指令或脚本列表‌:保存常用发送命令(如 16 进制指令集),用于调试或自动化测试(如 Python/LabVIEW 上位机)。

‌多语言界面支持‌:节名对应语言(如 [English]、[Chinese]),键值存界面文本,实现简易本地化。

‌调试与现场部署‌:客户可手动编辑 INI 文件调整参数(如校准系数、超时时间),无需数据库或复杂配置工具,契合工业现场“简单可靠”需求。‌‌

虽 XML/JSON/SQLite 更结构化,但 INI 因‌纯文本、无依赖、易编辑、跨平台兼容‌(Windows/Linux 均可解析),仍在工控、测试测量、嵌入式上位机中广泛使用,尤其适合参数不多、无需事务保障、强调可维护性的场景。注意不用于存储敏感信息(如密码)或高频写入数据(易损坏、无锁机制)。‌‌


INI文件(Initialization File)是一种结构简单、人类可读的纯文本配置格式,由节([section])、键值对(key=value)和注释(;或#开头)组成,当前仍广泛用于轻量级、非复杂场景的配置管理。

应用场景:配置通信参数,产线配置,程序配置,系统配置等
https://cloud.tencent.com/developer/article/2416602
https://www.jb51.net/program/334601b8z.htm

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utility;

namespace UI
{
    public partial class Form3 : Form
    {
        INIFileHelper helper = new INIFileHelper();
        INIFileHelper helper2 = new INIFileHelper("D://a.ini");

        public Form3()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /* helper.Set("section1", "key1", "value1");
             helper.Set("section2", "name", "张三");*/

            helper2.Set("section1", "key1", "value1");
            helper2.Set("section1", "key2", "value2");
            helper2.Set("section2", "name", "张三");
            helper2.Set("section2", "age", "20");


            MessageBox.Show("写入成功!");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //string result = helper.Get("section2", "name");
            string result = helper2.Get("section2", "name");
            MessageBox.Show(result);

        }
    }
}

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Utility
{
    public class INIFileHelper
    {
        private string path = Environment.CurrentDirectory + "\\" + "config.ini";

        public INIFileHelper() { }

        public INIFileHelper(string path)
        {
            this.path = path;
        }

        // C#中如何调用其他语言编写动态链接库?

        // kernel32就是windows系统自带的一个动态链接库,它提供了一系列的API,用来操作ini文件。但不是C#编写的源。 将来操作系统中有很其他语言(C或C++)编写的动态链接库,如user32.dll。动态链接库(Dynamic Link Library)。kernel32.dll在操作系统的C:\Windows\System32目录下。

        // DllImport特性专门用来导入动态链接库的API
        // 把某个动态链接库中的API导入到C#程序中时,有些导入细节:
        // 1。必须是静态的static, 且外部的extern(不是用C#语言编写的)
        // 2。导入动态链接库时,DllImport("动态链接库的名称"),其他的参数都是可选的
        [DllImport("kernel32.dll")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        /// <summary>
		/// 写INI文件
		/// </summary>
		/// <param name="section">写入的节点</param>
		/// <param name="key">键</param>
		/// <param name="val">值</param>
		public void Set(string section, string key, string val)
        {
            WritePrivateProfileString(section, key, val, this.path);
        }

        /// <summary>
        /// 读取INI文件
        /// </summary>
        /// <param name="section">读取的节点</param>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public string Get(string section, string key)
        {
            StringBuilder temp = new StringBuilder(255);
            GetPrivateProfileString(section, key, "", temp, 255, this.path);
            return temp.ToString();
        }
    }
}

更多推荐