using System; using System.Collections.Generic; using System.Data.SQLite; using System.IO; namespace DeviceService.Driver { /// /// 驱动信息 SQLite 持久化:数据库文件位于 应用根目录\Config\Drivers.db。 /// /// 表结构: /// - DriverPackage:已加载的驱动包(Driver 根目录下的一个子文件夹) /// - DriverType:驱动包内带 [DriverDesc] 注解的驱动类型((类型, 品牌) 定位) /// /// 所有操作失败仅通过 log 上报,不会中断驱动加载流程。 /// public sealed class DriverDatabase { private static readonly object _staticSync = new object(); private static DriverDatabase _instance; public static DriverDatabase Instance { get { lock (_staticSync) { return _instance ??= new DriverDatabase(); } } } /// 配置目录:应用根目录\Config。 public static string ConfigDirectory => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config"); /// 数据库文件路径。 public static string DatabasePath => Path.Combine(ConfigDirectory, "Drivers.db"); private readonly object _sync = new object(); private bool _initialized; private DriverDatabase() { } /// 确保 Config 目录与库表结构存在。失败返回 false 并通过 log 上报。 private bool EnsureReady(Action log) { if (_initialized) { return true; } try { if (!Directory.Exists(ConfigDirectory)) { Directory.CreateDirectory(ConfigDirectory); } using (var conn = Open()) using (var cmd = conn.CreateCommand()) { cmd.CommandText = @" CREATE TABLE IF NOT EXISTS DriverPackage ( Folder TEXT PRIMARY KEY, Directory TEXT NOT NULL, AssemblyCount INTEGER NOT NULL DEFAULT 0, ScanTime TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS DriverType ( Id INTEGER PRIMARY KEY AUTOINCREMENT, PackageFolder TEXT NOT NULL, AssemblyFile TEXT NOT NULL, FullName TEXT NOT NULL, DriverType TEXT, Brand TEXT, UNIQUE(PackageFolder, FullName) ); CREATE INDEX IF NOT EXISTS IX_DriverType_Type_Brand ON DriverType(DriverType, Brand);"; cmd.ExecuteNonQuery(); } _initialized = true; return true; } catch (Exception ex) { log?.Invoke($"[驱动库] 初始化失败({DatabasePath}): {ex.Message}"); return false; } } private SQLiteConnection Open() { var conn = new SQLiteConnection($"Data Source={DatabasePath};Version=3;"); conn.Open(); return conn; } /// 写入(覆盖)一个驱动包及其内部全部驱动类型的记录。 public void SavePackage(DriverPackage package, Action log = null) { if (package == null) { return; } if (!EnsureReady(log)) { return; } try { lock (_sync) { using (var conn = Open()) using (var tx = conn.BeginTransaction()) { ExecuteNonQuery(conn, "DELETE FROM DriverType WHERE PackageFolder = @f", tx, ("@f", package.Folder)); ExecuteNonQuery(conn, "DELETE FROM DriverPackage WHERE Folder = @f", tx, ("@f", package.Folder)); var assemblies = package.Assemblies ?? new DriverAssemblyInfo[0]; ExecuteNonQuery(conn, "INSERT INTO DriverPackage(Folder, Directory, AssemblyCount, ScanTime) VALUES(@f, @d, @c, @t)", tx, ("@f", package.Folder), ("@d", package.Directory ?? string.Empty), ("@c", assemblies.Length.ToString()), ("@t", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); int typeCount = 0; foreach (var asm in assemblies) { foreach (var type in asm.Types ?? new DriverTypeInfo[0]) { ExecuteNonQuery(conn, @"INSERT OR REPLACE INTO DriverType(PackageFolder, AssemblyFile, FullName, DriverType, Brand) VALUES(@p, @a, @n, @t, @b)", tx, ("@p", package.Folder), ("@a", asm.FileName ?? string.Empty), ("@n", type.FullName ?? string.Empty), ("@t", type.DriverType ?? string.Empty), ("@b", type.Brand ?? string.Empty)); typeCount++; } } tx.Commit(); log?.Invoke($"[驱动库] 已保存 {package.Folder}({assemblies.Length} 个 dll,{typeCount} 个驱动类型)"); } } } catch (Exception ex) { log?.Invoke($"[驱动库] 保存 {package.Folder} 失败: {ex.Message}"); } } /// 删除一个驱动包(及其全部驱动类型)的记录。 public void RemovePackage(string folder, Action log = null) { if (string.IsNullOrEmpty(folder) || !EnsureReady(log)) { return; } try { lock (_sync) { using (var conn = Open()) using (var tx = conn.BeginTransaction()) { ExecuteNonQuery(conn, "DELETE FROM DriverType WHERE PackageFolder = @f", tx, ("@f", folder)); ExecuteNonQuery(conn, "DELETE FROM DriverPackage WHERE Folder = @f", tx, ("@f", folder)); tx.Commit(); } } log?.Invoke($"[驱动库] 已移除 {folder} 的记录"); } catch (Exception ex) { log?.Invoke($"[驱动库] 移除 {folder} 失败: {ex.Message}"); } } /// 读取库中全部驱动类型记录(供界面/查询使用)。 public IReadOnlyList LoadDriverTypes(Action log = null) { var result = new List(); if (!EnsureReady(log)) { return result; } try { lock (_sync) { using (var conn = Open()) using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT PackageFolder, AssemblyFile, FullName, DriverType, Brand FROM DriverType ORDER BY DriverType, Brand, FullName"; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { result.Add(new DriverTypeInfo { FullName = GetString(reader, "FullName"), DriverType = GetString(reader, "DriverType"), Brand = GetString(reader, "Brand") }); } } } } } catch (Exception ex) { log?.Invoke($"[驱动库] 读取驱动类型失败: {ex.Message}"); } return result; } private static void ExecuteNonQuery(SQLiteConnection conn, string sql, SQLiteTransaction tx, params (string Name, string Value)[] parameters) { using (var cmd = conn.CreateCommand()) { cmd.Transaction = tx; cmd.CommandText = sql; foreach (var (name, value) in parameters) { cmd.Parameters.AddWithValue(name, value); } cmd.ExecuteNonQuery(); } } private static string GetString(SQLiteDataReader reader, string column) { var value = reader[column]; return value == DBNull.Value ? string.Empty : value.ToString(); } } }