From de20b506f00d72e0b1dae7ffbdaac8b144dd3a4c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 31 Aug 2025 00:25:22 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E5=88=86=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/DeviceIdentifier.cs | 2020 ++++-------------------- 1 file changed, 265 insertions(+), 1755 deletions(-) diff --git a/Ink Canvas/Helpers/DeviceIdentifier.cs b/Ink Canvas/Helpers/DeviceIdentifier.cs index 79140029..82bc3897 100644 --- a/Ink Canvas/Helpers/DeviceIdentifier.cs +++ b/Ink Canvas/Helpers/DeviceIdentifier.cs @@ -1,4 +1,3 @@ -using Microsoft.Win32; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -16,26 +15,10 @@ namespace Ink_Canvas.Helpers /// internal static class DeviceIdentifier { - // 多重备份路径策略 + // 文件路径策略 private static readonly string DeviceIdFilePath = Path.Combine(App.RootPath, "device_id.dat"); - private static readonly string UsageStatsFilePath = Path.Combine(App.RootPath, "usage_stats.json"); - - // 使用频率数据的多重隐藏备份路径 - private static readonly string BackupDeviceIdPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - "ICC", ".sys", "device.dat"); - private static readonly string BackupUsageStatsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - "ICC", ".sys", "usage.dat"); - - // 使用频率数据的额外隐藏备份位置 - private static readonly string SecondaryUsageBackupPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Microsoft", "Windows", ".icc", "usage_backup.tmp"); - private static readonly string TertiaryUsageBackupPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - "ICC", ".cache", "usage_cache.dat"); - private static readonly string QuaternaryUsageBackupPath = Path.Combine(Path.GetTempPath(), - ".icc_temp", "usage_temp.dat"); - - // 数据完整性验证密钥 - private static readonly string DataIntegrityKey = "ICC_DEVICE_INTEGRITY_2024"; + private static readonly string UsageStatsFilePath = Path.Combine(App.RootPath, "usage_stats.enc"); + private static readonly string UsageStatsBackupPath = Path.Combine(App.RootPath, "saves", "usage_stats_backup.enc"); private static readonly string DeviceId; private static readonly object fileLock = new object(); @@ -44,16 +27,6 @@ namespace Ink_Canvas.Helpers { // 在静态构造函数中初始化设备ID DeviceId = GetOrCreateDeviceId(); - - // 执行数据完整性检查和自动修复 - try - { - PerformDataIntegrityCheck(); - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 初始化时数据完整性检查失败: {ex.Message}", LogHelper.LogType.Error); - } } /// @@ -66,7 +39,7 @@ namespace Ink_Canvas.Helpers } /// - /// 获取或创建设备ID(内部方法)- 支持多重备份恢复 + /// 获取或创建设备ID /// private static string GetOrCreateDeviceId() { @@ -79,35 +52,15 @@ namespace Ink_Canvas.Helpers if (!string.IsNullOrEmpty(deviceId)) { LogHelper.WriteLogToFile($"DeviceIdentifier | 从主文件读取设备ID: {deviceId}"); - // 确保备份同步 - SaveDeviceIdToAllLocations(deviceId); return deviceId; } - // 2. 尝试从备份文件恢复 - deviceId = LoadDeviceIdFromFile(BackupDeviceIdPath); - if (!string.IsNullOrEmpty(deviceId)) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从备份文件恢复设备ID: {deviceId}"); - SaveDeviceIdToAllLocations(deviceId); - return deviceId; - } - - // 3. 尝试从注册表恢复 - deviceId = LoadDeviceIdFromRegistry(); - if (!string.IsNullOrEmpty(deviceId)) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表恢复设备ID: {deviceId}"); - SaveDeviceIdToAllLocations(deviceId); - return deviceId; - } - - // 4. 生成新的设备ID + // 2. 生成新的设备ID string newDeviceId = GenerateDeviceId(); LogHelper.WriteLogToFile($"DeviceIdentifier | 生成新设备ID: {newDeviceId}"); - // 5. 保存到所有位置 - SaveDeviceIdToAllLocations(newDeviceId); + // 3. 保存到主文件 + SaveDeviceIdToFile(DeviceIdFilePath, newDeviceId); return newDeviceId; } @@ -350,47 +303,6 @@ namespace Ink_Canvas.Helpers return null; } - /// - /// 从注册表加载设备ID - /// - private static string LoadDeviceIdFromRegistry() - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(@"Software\ICC\DeviceInfo")) - { - if (key != null) - { - var value = key.GetValue("DeviceId") as string; - if (IsValidDeviceId(value)) - { - return value; - } - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表加载设备ID失败: {ex.Message}", LogHelper.LogType.Error); - } - return null; - } - - /// - /// 保存设备ID到所有位置 - /// - private static void SaveDeviceIdToAllLocations(string deviceId) - { - // 保存到主文件 - SaveDeviceIdToFile(DeviceIdFilePath, deviceId); - - // 保存到备份文件 - SaveDeviceIdToFile(BackupDeviceIdPath, deviceId); - - // 保存到注册表 - SaveDeviceIdToRegistry(deviceId); - } - /// /// 保存设备ID到文件 /// @@ -403,50 +315,19 @@ namespace Ink_Canvas.Helpers if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); - // 设置隐藏属性 - if (filePath.Contains(".sys")) - { - var dirInfo = new DirectoryInfo(directory); - dirInfo.Attributes |= FileAttributes.Hidden | FileAttributes.System; - } } File.WriteAllText(filePath, deviceId); - // 设置文件属性为隐藏和系统文件 - if (filePath.Contains(".sys")) - { - var fileInfo = new FileInfo(filePath); - fileInfo.Attributes |= FileAttributes.Hidden | FileAttributes.System; - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 设备ID已保存到: {filePath}"); + LogHelper.WriteLogToFile($"DeviceIdentifier | 设备ID已保存到: {filePath}"); } catch (Exception ex) { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 保存设备ID到文件失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); + LogHelper.WriteLogToFile($"DeviceIdentifier | 保存设备ID到文件失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); } } - /// - /// 保存设备ID到注册表 - /// - private static void SaveDeviceIdToRegistry(string deviceId) - { - try - { - using (var key = Registry.CurrentUser.CreateSubKey(@"Software\ICC\DeviceInfo")) - { - key?.SetValue("DeviceId", deviceId); - key?.SetValue("LastUpdate", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); - } - // LogHelper.WriteLogToFile("DeviceIdentifier | 设备ID已保存到注册表"); - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 保存设备ID到注册表失败: {ex.Message}", LogHelper.LogType.Error); - } - } + /// /// 使用频率统计数据结构(优化至秒级精度) @@ -487,9 +368,6 @@ namespace Ink_Canvas.Helpers [JsonProperty("usageFrequency")] public UsageFrequency UsageFrequency { get; set; } - [JsonProperty("dataHash")] - public string DataHash { get; set; } - [JsonProperty("lastModified")] public DateTime LastModified { get; set; } @@ -613,57 +491,6 @@ namespace Ink_Canvas.Helpers // 同时更新旧字段以保持兼容性 WeeklyUsageMinutes = WeeklyUsageSeconds / 60; } - - - - /// - /// 计算数据哈希值用于完整性验证(秒级精度) - /// - public void UpdateDataHash() - { - // 使用秒级精度数据计算哈希 - var dataString = $"{DeviceId}|{LaunchCount}|{TotalUsageSeconds}|{LastLaunchTime:yyyyMMddHHmmss}|{WeeklyLaunchCount}|{WeeklyUsageSeconds}|{DataIntegrityKey}"; - using (var sha256 = SHA256.Create()) - { - var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(dataString)); - DataHash = Convert.ToBase64String(hashBytes); - } - LastModified = DateTime.Now; - } - - /// - /// 验证数据完整性(秒级精度) - /// - public bool VerifyDataIntegrity() - { - try - { - // 首先尝试使用秒级精度验证 - var dataString = $"{DeviceId}|{LaunchCount}|{TotalUsageSeconds}|{LastLaunchTime:yyyyMMddHHmmss}|{WeeklyLaunchCount}|{WeeklyUsageSeconds}|{DataIntegrityKey}"; - using (var sha256 = SHA256.Create()) - { - var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(dataString)); - var expectedHash = Convert.ToBase64String(hashBytes); - if (DataHash == expectedHash) - { - return true; - } - } - - // 如果秒级精度验证失败,尝试使用旧的分钟精度验证(向后兼容) - var oldDataString = $"{DeviceId}|{LaunchCount}|{TotalUsageMinutes}|{LastLaunchTime:yyyyMMddHHmmss}|{WeeklyLaunchCount}|{WeeklyUsageMinutes}|{DataIntegrityKey}"; - using (var sha256 = SHA256.Create()) - { - var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(oldDataString)); - var expectedHash = Convert.ToBase64String(hashBytes); - return DataHash == expectedHash; - } - } - catch - { - return false; - } - } } /// @@ -738,9 +565,6 @@ namespace Ink_Canvas.Helpers // 计算使用频率 CalculateUsageFrequency(stats); - // 更新数据完整性哈希 - stats.UpdateDataHash(); - SaveUsageStats(stats); LogHelper.WriteLogToFile($"DeviceIdentifier | 记录应用启动 - 设备ID: {DeviceId}, 总启动: {stats.LaunchCount}次, 本周启动: {stats.WeeklyLaunchCount}次"); @@ -794,9 +618,6 @@ namespace Ink_Canvas.Helpers // 重新计算使用频率 CalculateUsageFrequency(stats); - // 更新数据完整性哈希 - stats.UpdateDataHash(); - SaveUsageStats(stats); LogHelper.WriteLogToFile($"DeviceIdentifier | 记录应用退出 - 本次会话: {FormatDuration(sessionSeconds)}, " + @@ -992,53 +813,42 @@ namespace Ink_Canvas.Helpers } /// - /// 加载使用统计 - 支持多重备份恢复和智能反篡改 + /// 加载使用统计 /// private static UsageStats LoadUsageStats() { try { - // 智能恢复:收集所有可用的数据源,选择最可信的 - var allDataSources = CollectAllUsageDataSources(); - - // 如果找到有效数据,返回最可信的 - if (allDataSources.Count > 0) + // 1. 尝试从主文件加载 + var stats = LoadUsageStatsFromFile(UsageStatsFilePath); + if (stats != null) { - var bestData = SelectMostTrustedData(allDataSources); - if (bestData != null) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 使用最可信数据源恢复使用统计: {bestData.Source}"); - - // 执行数据迁移(如果需要) - bestData.Stats.MigrateToSecondsPrecision(); - - // 确保备份同步 - SaveUsageStatsToAllLocations(bestData.Stats); - return bestData.Stats; - } - } - - // LogHelper.WriteLogToFile("DeviceIdentifier | 所有数据源都不可用,检查是否有部分可恢复数据", LogHelper.LogType.Warning); - - // 如果没有完全可信的数据,尝试从部分损坏的数据中恢复 - var partiallyRecoveredData = AttemptPartialDataRecovery(allDataSources); - if (partiallyRecoveredData != null) - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 从部分损坏数据中恢复使用统计"); - // 执行数据迁移(如果需要) - partiallyRecoveredData.MigrateToSecondsPrecision(); - - SaveUsageStatsToAllLocations(partiallyRecoveredData); - return partiallyRecoveredData; + stats.MigrateToSecondsPrecision(); + return stats; } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 加载使用统计失败: {ex.Message}", LogHelper.LogType.Error); - } - // 返回新的统计对象(秒级精度) + // 2. 尝试从备份文件加载 + stats = LoadUsageStatsFromFile(UsageStatsBackupPath); + if (stats != null) + { + LogHelper.WriteLogToFile("DeviceIdentifier | 从备份文件恢复使用统计"); + stats.MigrateToSecondsPrecision(); + // 尝试恢复主文件 + try + { + SaveUsageStatsToFile(UsageStatsFilePath, stats); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 恢复主文件失败: {ex.Message}", LogHelper.LogType.Warning); + } + return stats; + } + + + + // 如果所有文件都不存在或损坏,返回新的统计对象 var newStats = new UsageStats { DeviceId = DeviceId, @@ -1053,36 +863,47 @@ namespace Ink_Canvas.Helpers UsageFrequency = UsageFrequency.Medium }; - // 更新数据完整性哈希 - newStats.UpdateDataHash(); - - // 保存新统计到所有位置 - SaveUsageStatsToAllLocations(newStats); + // 保存新统计到文件 + SaveUsageStatsToFile(UsageStatsFilePath, newStats); return newStats; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 加载使用统计失败: {ex.Message}", LogHelper.LogType.Error); + + // 返回默认统计对象 + return new UsageStats + { + DeviceId = DeviceId, + LastLaunchTime = DateTime.Now, + LaunchCount = 0, + TotalUsageSeconds = 0, + AverageSessionSeconds = 0, + TotalUsageMinutes = 0, + AverageSessionMinutes = 0, + LastUpdateCheck = DateTime.MinValue, + UpdatePriority = UpdatePriority.Medium, + UsageFrequency = UsageFrequency.Medium + }; + } } /// - /// 保存使用统计 - 多重备份 + /// 保存使用统计 /// private static void SaveUsageStats(UsageStats stats) { - SaveUsageStatsToAllLocations(stats); + // 保存到主文件 + SaveUsageStatsToFile(UsageStatsFilePath, stats); + + // 保存到备份文件 + SaveUsageStatsToFile(UsageStatsBackupPath, stats); } - /// - /// 数据源信息结构 - /// - private class DataSourceInfo - { - public UsageStats Stats { get; set; } - public string Source { get; set; } - public bool IsIntegrityValid { get; set; } - public DateTime LastModified { get; set; } - public int TrustScore { get; set; } - } + /// - /// 从文件加载使用统计(带完整性验证,但不丢弃篡改数据) + /// 从文件加载使用统计(解密) /// private static UsageStats LoadUsageStatsFromFile(string filePath) { @@ -1090,28 +911,28 @@ namespace Ink_Canvas.Helpers { if (File.Exists(filePath)) { - string json = File.ReadAllText(filePath); - var stats = JsonConvert.DeserializeObject(json); - if (stats != null && !string.IsNullOrEmpty(stats.DeviceId)) + // 尝试解密文件 + var stats = LoadUsageStatsFromEncryptedFile(filePath); + if (stats != null) { - // 验证数据完整性 - if (!string.IsNullOrEmpty(stats.DataHash)) - { - if (stats.VerifyDataIntegrity()) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 数据完整性验证通过: {filePath}"); - return stats; - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 数据完整性验证失败,可能被篡改: {filePath}", LogHelper.LogType.Warning); - return null; // 数据被篡改,不使用 - } - - // 旧版本数据,没有哈希值,更新哈希后返回 - // LogHelper.WriteLogToFile($"DeviceIdentifier | 检测到旧版本数据,正在更新完整性哈希: {filePath}"); - stats.UpdateDataHash(); return stats; } + + // 如果解密失败,尝试作为普通JSON文件读取(向后兼容) + try + { + string json = File.ReadAllText(filePath); + var plainStats = JsonConvert.DeserializeObject(json); + if (plainStats != null && !string.IsNullOrEmpty(plainStats.DeviceId)) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 从普通JSON文件加载使用统计: {filePath}"); + return plainStats; + } + } + catch + { + // 忽略JSON解析错误 + } } } catch (Exception ex) @@ -1122,557 +943,67 @@ namespace Ink_Canvas.Helpers } /// - /// 从文件加载使用统计(包括被篡改的数据,用于恢复分析) + /// 从加密文件加载使用统计 /// - private static DataSourceInfo LoadUsageStatsFromFileWithInfo(string filePath, string sourceName) + private static UsageStats LoadUsageStatsFromEncryptedFile(string filePath) { try { if (File.Exists(filePath)) { - string json = File.ReadAllText(filePath); - var stats = JsonConvert.DeserializeObject(json); - if (stats != null && !string.IsNullOrEmpty(stats.DeviceId)) + byte[] encryptedData = File.ReadAllBytes(filePath); + + if (encryptedData.Length < 32) // SHA256校验和长度为32字节 { - var fileInfo = new FileInfo(filePath); - var dataSource = new DataSourceInfo + LogHelper.WriteLogToFile($"DeviceIdentifier | 加密文件格式错误: {filePath}", LogHelper.LogType.Error); + return null; + } + + // 提取校验和和加密数据 + byte[] checksum = new byte[32]; + byte[] data = new byte[encryptedData.Length - 32]; + Array.Copy(encryptedData, 0, checksum, 0, 32); + Array.Copy(encryptedData, 32, data, 0, data.Length); + + // 使用SHA256生成解密密钥 + using (var sha256 = SHA256.Create()) + { + byte[] keyBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(DeviceId + "ICC_Usage_Stats_Salt")); + + // XOR解密 + byte[] decryptedData = new byte[data.Length]; + for (int i = 0; i < data.Length; i++) { - Stats = stats, - Source = sourceName, - LastModified = stats.LastModified != DateTime.MinValue ? stats.LastModified : fileInfo.LastWriteTime, - IsIntegrityValid = false, - TrustScore = 0 - }; - - // 验证数据完整性 - if (!string.IsNullOrEmpty(stats.DataHash)) - { - dataSource.IsIntegrityValid = stats.VerifyDataIntegrity(); - dataSource.TrustScore = dataSource.IsIntegrityValid ? 100 : 20; // 完整数据100分,篡改数据20分 + decryptedData[i] = (byte)(data[i] ^ keyBytes[i % keyBytes.Length]); } - else + + // 验证校验和 + byte[] computedChecksum = sha256.ComputeHash(decryptedData); + if (!checksum.SequenceEqual(computedChecksum)) { - // 旧版本数据,中等信任度 - dataSource.IsIntegrityValid = true; - dataSource.TrustScore = 60; - stats.UpdateDataHash(); + LogHelper.WriteLogToFile($"DeviceIdentifier | 加密文件校验和验证失败: {filePath}", LogHelper.LogType.Error); + return null; + } + + string json = Encoding.UTF8.GetString(decryptedData); + var stats = JsonConvert.DeserializeObject(json); + if (stats != null && !string.IsNullOrEmpty(stats.DeviceId)) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 从加密文件成功加载使用统计: {filePath}"); + return stats; } - - return dataSource; } } } catch (Exception ex) { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从文件加载数据源信息失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); + LogHelper.WriteLogToFile($"DeviceIdentifier | 从加密文件加载使用统计失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); } return null; } - /// - /// 收集所有可用的使用统计数据源 - /// - private static List CollectAllUsageDataSources() - { - var dataSources = new List(); - - try - { - // 1. 收集文件数据源 - var fileSources = new[] - { - new { Path = UsageStatsFilePath, Name = "主文件" }, - new { Path = BackupUsageStatsPath, Name = "第一备份" }, - new { Path = SecondaryUsageBackupPath, Name = "第二备份" }, - new { Path = TertiaryUsageBackupPath, Name = "第三备份" }, - new { Path = QuaternaryUsageBackupPath, Name = "第四备份" } - }; - - foreach (var source in fileSources) - { - var dataSource = LoadUsageStatsFromFileWithInfo(source.Path, source.Name); - if (dataSource != null) - { - dataSources.Add(dataSource); - } - } - - // 2. 收集注册表数据源 - var registrySource = LoadUsageStatsFromRegistryWithInfo(@"Software\ICC\DeviceInfo", "主注册表"); - if (registrySource != null) - { - dataSources.Add(registrySource); - } - - // 3. 收集备用注册表数据源 - var backupRegistryPaths = new[] - { - new { Path = @"Software\Microsoft\Windows\CurrentVersion\ICC", Name = "备用注册表1" }, - new { Path = @"Software\Classes\.icc\UsageData", Name = "备用注册表2" }, - new { Path = @"Software\ICC\Config\Usage", Name = "备用注册表3" } - }; - - foreach (var regPath in backupRegistryPaths) - { - var regSource = LoadUsageStatsFromBackupRegistryWithInfo(regPath.Path, regPath.Name); - if (regSource != null) - { - dataSources.Add(regSource); - } - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 收集到 {dataSources.Count} 个数据源"); - return dataSources; - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 收集数据源失败: {ex.Message}", LogHelper.LogType.Error); - return dataSources; - } - } - - /// - /// 选择最可信的数据源 - /// - private static DataSourceInfo SelectMostTrustedData(List dataSources) - { - try - { - // 首先尝试找到完整性验证通过的数据 - var validSources = dataSources.Where(d => d.IsIntegrityValid).ToList(); - - if (validSources.Count > 0) - { - // 在有效数据中选择最新的 - var bestValid = validSources.OrderByDescending(d => d.LastModified).First(); - // LogHelper.WriteLogToFile($"DeviceIdentifier | 选择完整性验证通过的最新数据: {bestValid.Source}"); - return bestValid; - } - - // 如果没有完整性验证通过的数据,选择信任度最高的 - var bestByTrust = dataSources.OrderByDescending(d => d.TrustScore).ThenByDescending(d => d.LastModified).FirstOrDefault(); - if (bestByTrust != null) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 选择信任度最高的数据: {bestByTrust.Source} (信任度: {bestByTrust.TrustScore})", LogHelper.LogType.Warning); - return bestByTrust; - } - - return null; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 选择最可信数据失败: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 尝试从部分损坏的数据中恢复 - /// - private static UsageStats AttemptPartialDataRecovery(List dataSources) - { - try - { - if (dataSources.Count == 0) - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 没有可用数据源进行部分恢复"); - return null; - } - - // 从所有数据源中提取可信的字段 - var recoveredStats = new UsageStats - { - DeviceId = DeviceId, - LastLaunchTime = DateTime.Now, - LaunchCount = 0, - TotalUsageMinutes = 0, - AverageSessionMinutes = 0, - LastUpdateCheck = DateTime.MinValue, - UpdatePriority = UpdatePriority.Medium, - UsageFrequency = UsageFrequency.Medium - }; - - // 使用多数投票或最大值策略恢复关键数据(秒级精度) - var launchCounts = dataSources.Where(d => d.Stats.LaunchCount > 0).Select(d => d.Stats.LaunchCount).ToList(); - var usageSeconds = dataSources.Where(d => d.Stats.TotalUsageSeconds > 0).Select(d => d.Stats.TotalUsageSeconds).ToList(); - var usageMinutes = dataSources.Where(d => d.Stats.TotalUsageMinutes > 0).Select(d => d.Stats.TotalUsageMinutes).ToList(); - - if (launchCounts.Count > 0) - { - recoveredStats.LaunchCount = (int)launchCounts.Average(); // 使用平均值 - } - - // 优先使用秒级数据,如果没有则使用分钟数据转换 - if (usageSeconds.Count > 0) - { - recoveredStats.TotalUsageSeconds = (long)usageSeconds.Average(); // 使用平均值 - recoveredStats.TotalUsageMinutes = recoveredStats.TotalUsageSeconds / 60; // 兼容性 - } - else if (usageMinutes.Count > 0) - { - recoveredStats.TotalUsageMinutes = (long)usageMinutes.Average(); // 使用平均值 - recoveredStats.TotalUsageSeconds = recoveredStats.TotalUsageMinutes * 60; // 转换为秒 - } - - // 重新计算平均会话时长(秒级精度) - if (recoveredStats.LaunchCount > 0) - { - recoveredStats.AverageSessionSeconds = (double)recoveredStats.TotalUsageSeconds / recoveredStats.LaunchCount; - recoveredStats.AverageSessionMinutes = recoveredStats.AverageSessionSeconds / 60; // 兼容性 - } - - // 重新计算使用频率 - CalculateUsageFrequency(recoveredStats); - - // 更新数据完整性哈希 - recoveredStats.UpdateDataHash(); - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 部分数据恢复完成 - 启动次数: {recoveredStats.LaunchCount}, 使用时长: {FormatDuration(recoveredStats.TotalUsageSeconds)}"); - return recoveredStats; - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 部分数据恢复失败: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 从注册表加载使用统计(带数据源信息) - /// - private static DataSourceInfo LoadUsageStatsFromRegistryWithInfo(string registryPath, string sourceName) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(registryPath)) - { - if (key != null) - { - var deviceId = key.GetValue("DeviceId") as string; - var launchCount = key.GetValue("LaunchCount"); - - // 秒级精度数据 - var totalSeconds = key.GetValue("TotalUsageSeconds"); - var avgSessionSeconds = key.GetValue("AverageSessionSeconds"); - - // 兼容性:分钟精度数据 - var totalMinutes = key.GetValue("TotalUsageMinutes"); - var avgSessionMinutes = key.GetValue("AverageSessionMinutes"); - - var lastLaunch = key.GetValue("LastLaunchTime") as string; - var priority = key.GetValue("UpdatePriority"); - var frequency = key.GetValue("UsageFrequency"); - var dataHash = key.GetValue("DataHash") as string; - var lastUpdate = key.GetValue("LastUpdate") as string; - - // 每周统计数据(秒级精度) - var weeklyLaunchCount = key.GetValue("WeeklyLaunchCount"); - var weeklyUsageSeconds = key.GetValue("WeeklyUsageSeconds"); - var lastWeekUsageSeconds = key.GetValue("LastWeekUsageSeconds"); - - // 兼容性:分钟精度数据 - var weeklyUsageMinutes = key.GetValue("WeeklyUsageMinutes"); - var lastWeekUsageMinutes = key.GetValue("LastWeekUsageMinutes"); - - var weekStartDate = key.GetValue("WeekStartDate") as string; - var lastWeekLaunchCount = key.GetValue("LastWeekLaunchCount"); - - if (!string.IsNullOrEmpty(deviceId) && launchCount != null) - { - var stats = new UsageStats - { - DeviceId = deviceId, - LaunchCount = Convert.ToInt32(launchCount), - - // 秒级精度数据 - TotalUsageSeconds = totalSeconds != null ? Convert.ToInt64(totalSeconds) : 0, - AverageSessionSeconds = avgSessionSeconds != null ? Convert.ToDouble(avgSessionSeconds) : 0, - - // 兼容性:分钟精度数据 - TotalUsageMinutes = totalMinutes != null ? Convert.ToInt64(totalMinutes) : 0, - AverageSessionMinutes = avgSessionMinutes != null ? Convert.ToDouble(avgSessionMinutes) : 0, - - LastLaunchTime = DateTime.TryParse(lastLaunch, out var dt) ? dt : DateTime.Now, - UpdatePriority = priority != null ? (UpdatePriority)Convert.ToInt32(priority) : UpdatePriority.Medium, - UsageFrequency = frequency != null ? (UsageFrequency)Convert.ToInt32(frequency) : UsageFrequency.Medium, - DataHash = dataHash, - LastUpdateCheck = DateTime.MinValue, - - // 每周统计数据(秒级精度) - WeeklyLaunchCount = weeklyLaunchCount != null ? Convert.ToInt32(weeklyLaunchCount) : 0, - WeeklyUsageSeconds = weeklyUsageSeconds != null ? Convert.ToInt64(weeklyUsageSeconds) : 0, - LastWeekUsageSeconds = lastWeekUsageSeconds != null ? Convert.ToInt64(lastWeekUsageSeconds) : 0, - - // 兼容性:分钟精度数据 - WeeklyUsageMinutes = weeklyUsageMinutes != null ? Convert.ToInt64(weeklyUsageMinutes) : 0, - LastWeekUsageMinutes = lastWeekUsageMinutes != null ? Convert.ToInt64(lastWeekUsageMinutes) : 0, - - WeekStartDate = DateTime.TryParse(weekStartDate, out var wsd) ? wsd : DateTime.MinValue, - LastWeekLaunchCount = lastWeekLaunchCount != null ? Convert.ToInt32(lastWeekLaunchCount) : 0 - }; - - // 执行数据迁移(如果需要) - stats.MigrateToSecondsPrecision(); - - // 重新计算平均会话时长 - if (stats.LaunchCount > 0 && stats.AverageSessionSeconds == 0) - { - stats.AverageSessionSeconds = (double)stats.TotalUsageSeconds / stats.LaunchCount; - stats.AverageSessionMinutes = stats.AverageSessionSeconds / 60; - } - - var dataSource = new DataSourceInfo - { - Stats = stats, - Source = sourceName, - LastModified = DateTime.TryParse(lastUpdate, out var updateTime) ? updateTime : DateTime.Now, - IsIntegrityValid = false, - TrustScore = 80 // 注册表数据信任度较高 - }; - - // 验证数据完整性 - if (!string.IsNullOrEmpty(stats.DataHash)) - { - dataSource.IsIntegrityValid = stats.VerifyDataIntegrity(); - dataSource.TrustScore = dataSource.IsIntegrityValid ? 100 : 30; - } - - return dataSource; - } - } - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表加载数据源信息失败 ({registryPath}): {ex.Message}", LogHelper.LogType.Error); - } - return null; - } - - /// - /// 从备用注册表位置加载使用统计(带数据源信息) - /// - private static DataSourceInfo LoadUsageStatsFromBackupRegistryWithInfo(string registryPath, string sourceName) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(registryPath)) - { - if (key != null) - { - var launchCount = key.GetValue("LC"); - - // 秒级精度数据 - var totalSeconds = key.GetValue("TUS"); - var avgSessionSeconds = key.GetValue("ASS"); - - // 兼容性:分钟精度数据 - var totalMinutes = key.GetValue("TUM"); - var avgSessionMinutes = key.GetValue("ASM"); - - var lastLaunchBinary = key.GetValue("LLT"); - var priority = key.GetValue("UP"); - var frequency = key.GetValue("UF"); - var dataHash = key.GetValue("DH") as string; - var lastUpdateBinary = key.GetValue("LU"); - - // 每周统计数据(秒级精度) - var weeklyLaunchCount = key.GetValue("WLC"); - var weeklyUsageSeconds = key.GetValue("WUS"); - var lastWeekUsageSeconds = key.GetValue("LWUS"); - - // 兼容性:分钟精度数据 - var weeklyUsageMinutes = key.GetValue("WUM"); - var lastWeekUsageMinutes = key.GetValue("LWUM"); - - var weekStartDateBinary = key.GetValue("WSD"); - var lastWeekLaunchCount = key.GetValue("LWLC"); - - if (launchCount != null && (totalSeconds != null || totalMinutes != null)) - { - var stats = new UsageStats - { - DeviceId = DeviceId, - LaunchCount = Convert.ToInt32(launchCount), - - // 秒级精度数据 - TotalUsageSeconds = totalSeconds != null ? Convert.ToInt64(totalSeconds) : 0, - AverageSessionSeconds = avgSessionSeconds != null ? Convert.ToDouble(avgSessionSeconds) : 0, - - // 兼容性:分钟精度数据 - TotalUsageMinutes = totalMinutes != null ? Convert.ToInt64(totalMinutes) : 0, - AverageSessionMinutes = avgSessionMinutes != null ? Convert.ToDouble(avgSessionMinutes) : 0, - - LastLaunchTime = lastLaunchBinary != null ? DateTime.FromBinary(Convert.ToInt64(lastLaunchBinary)) : DateTime.Now, - UpdatePriority = priority != null ? (UpdatePriority)Convert.ToInt32(priority) : UpdatePriority.Medium, - UsageFrequency = frequency != null ? (UsageFrequency)Convert.ToInt32(frequency) : UsageFrequency.Medium, - DataHash = dataHash, - LastUpdateCheck = DateTime.MinValue, - - // 每周统计数据(秒级精度) - WeeklyLaunchCount = weeklyLaunchCount != null ? Convert.ToInt32(weeklyLaunchCount) : 0, - WeeklyUsageSeconds = weeklyUsageSeconds != null ? Convert.ToInt64(weeklyUsageSeconds) : 0, - LastWeekUsageSeconds = lastWeekUsageSeconds != null ? Convert.ToInt64(lastWeekUsageSeconds) : 0, - - // 兼容性:分钟精度数据 - WeeklyUsageMinutes = weeklyUsageMinutes != null ? Convert.ToInt64(weeklyUsageMinutes) : 0, - LastWeekUsageMinutes = lastWeekUsageMinutes != null ? Convert.ToInt64(lastWeekUsageMinutes) : 0, - - WeekStartDate = weekStartDateBinary != null ? DateTime.FromBinary(Convert.ToInt64(weekStartDateBinary)) : DateTime.MinValue, - LastWeekLaunchCount = lastWeekLaunchCount != null ? Convert.ToInt32(lastWeekLaunchCount) : 0 - }; - - // 执行数据迁移(如果需要) - stats.MigrateToSecondsPrecision(); - - // 重新计算平均会话时长 - if (stats.LaunchCount > 0 && stats.AverageSessionSeconds == 0) - { - stats.AverageSessionSeconds = (double)stats.TotalUsageSeconds / stats.LaunchCount; - stats.AverageSessionMinutes = stats.AverageSessionSeconds / 60; - } - - var dataSource = new DataSourceInfo - { - Stats = stats, - Source = sourceName, - LastModified = lastUpdateBinary != null ? DateTime.FromBinary(Convert.ToInt64(lastUpdateBinary)) : DateTime.Now, - IsIntegrityValid = false, - TrustScore = 75 // 备用注册表数据信任度中等 - }; - - // 验证数据完整性 - if (!string.IsNullOrEmpty(stats.DataHash)) - { - dataSource.IsIntegrityValid = stats.VerifyDataIntegrity(); - dataSource.TrustScore = dataSource.IsIntegrityValid ? 100 : 25; - } - - return dataSource; - } - } - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从备用注册表加载数据源信息失败 ({registryPath}): {ex.Message}", LogHelper.LogType.Error); - } - return null; - } - - /// - /// 从注册表加载使用统计(保持向后兼容) - /// - private static UsageStats LoadUsageStatsFromRegistry() - { - var dataSource = LoadUsageStatsFromRegistryWithInfo(@"Software\ICC\DeviceInfo", "主注册表"); - return dataSource?.Stats; - } - - /// - /// 从多个注册表位置加载使用统计(强化恢复) - /// - private static UsageStats LoadUsageStatsFromMultipleRegistryLocations() - { - var registryPaths = new[] - { - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(path)) - { - if (key != null) - { - var launchCount = key.GetValue("LC"); - var totalMinutes = key.GetValue("TUM"); - var lastLaunchBinary = key.GetValue("LLT"); - var priority = key.GetValue("UP"); - var frequency = key.GetValue("UF"); - var dataHash = key.GetValue("DH") as string; - - if (launchCount != null && totalMinutes != null) - { - var stats = new UsageStats - { - DeviceId = DeviceId, - LaunchCount = Convert.ToInt32(launchCount), - TotalUsageMinutes = Convert.ToInt64(totalMinutes), - LastLaunchTime = lastLaunchBinary != null ? DateTime.FromBinary(Convert.ToInt64(lastLaunchBinary)) : DateTime.Now, - UpdatePriority = priority != null ? (UpdatePriority)Convert.ToInt32(priority) : UpdatePriority.Medium, - UsageFrequency = frequency != null ? (UsageFrequency)Convert.ToInt32(frequency) : UsageFrequency.Medium, - DataHash = dataHash, - AverageSessionMinutes = 0, - LastUpdateCheck = DateTime.MinValue - }; - - // 重新计算平均会话时长 - if (stats.LaunchCount > 0) - { - stats.AverageSessionMinutes = (double)stats.TotalUsageMinutes / stats.LaunchCount; - } - - // 验证数据完整性(如果有哈希值) - if (!string.IsNullOrEmpty(stats.DataHash)) - { - if (stats.VerifyDataIntegrity()) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表位置恢复数据并验证完整性通过: {path}"); - return stats; - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 注册表位置数据完整性验证失败: {path}", LogHelper.LogType.Warning); - } - else - { - // 没有哈希值的旧数据,更新哈希后返回 - stats.UpdateDataHash(); - // LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表位置恢复旧版本数据: {path}"); - return stats; - } - } - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 从注册表位置加载失败 ({path}): {ex.Message}", LogHelper.LogType.Error); - } - } - - return null; - } - - /// - /// 保存使用统计到所有位置(强化版本 - 多重隐藏备份) - /// - private static void SaveUsageStatsToAllLocations(UsageStats stats) - { - // 保存到主文件 - SaveUsageStatsToFile(UsageStatsFilePath, stats); - - // 保存到第一备份文件 - SaveUsageStatsToFile(BackupUsageStatsPath, stats); - - // 保存到多个隐藏备份位置(专门针对使用频率数据保护) - SaveUsageStatsToFile(SecondaryUsageBackupPath, stats); - SaveUsageStatsToFile(TertiaryUsageBackupPath, stats); - SaveUsageStatsToFile(QuaternaryUsageBackupPath, stats); - - // 保存到注册表 - SaveUsageStatsToRegistry(stats); - - // 保存到注册表的多个位置 - SaveUsageStatsToMultipleRegistryLocations(stats); - } - - /// - /// 保存使用统计到文件 + /// + /// 保存使用统计到文件(加密) /// private static void SaveUsageStatsToFile(string filePath, UsageStats stats) { @@ -1683,161 +1014,42 @@ namespace Ink_Canvas.Helpers if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); - // 设置隐藏属性 - if (filePath.Contains(".sys")) - { - var dirInfo = new DirectoryInfo(directory); - dirInfo.Attributes |= FileAttributes.Hidden | FileAttributes.System; - } } string json = JsonConvert.SerializeObject(stats, Formatting.Indented); - File.WriteAllText(filePath, json); - - // 设置文件属性为隐藏和系统文件 - if (filePath.Contains(".sys")) + byte[] data = Encoding.UTF8.GetBytes(json); + + // 使用SHA256生成加密密钥(基于设备ID) + using (var sha256 = SHA256.Create()) { - var fileInfo = new FileInfo(filePath); - fileInfo.Attributes |= FileAttributes.Hidden | FileAttributes.System; - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 使用统计已保存到: {filePath}"); - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 保存使用统计到文件失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 保存使用统计到注册表 - /// - private static void SaveUsageStatsToRegistry(UsageStats stats) - { - try - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 开始保存使用统计到主注册表位置"); - - using (var key = Registry.CurrentUser.CreateSubKey(@"Software\ICC\DeviceInfo")) - { - if (key != null) + byte[] keyBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(DeviceId + "ICC_Usage_Stats_Salt")); + + // 简单的XOR加密 + byte[] encryptedData = new byte[data.Length]; + for (int i = 0; i < data.Length; i++) { - key.SetValue("DeviceId", stats.DeviceId); - key.SetValue("LaunchCount", stats.LaunchCount); - - // 秒级精度数据 - key.SetValue("TotalUsageSeconds", stats.TotalUsageSeconds); - key.SetValue("AverageSessionSeconds", stats.AverageSessionSeconds); - - // 兼容性:分钟精度数据 - key.SetValue("TotalUsageMinutes", stats.TotalUsageMinutes); - key.SetValue("AverageSessionMinutes", stats.AverageSessionMinutes); - - key.SetValue("LastLaunchTime", stats.LastLaunchTime.ToString("yyyy-MM-dd HH:mm:ss")); - key.SetValue("UpdatePriority", (int)stats.UpdatePriority); - key.SetValue("UsageFrequency", (int)stats.UsageFrequency); - key.SetValue("DataHash", stats.DataHash ?? ""); - key.SetValue("LastUpdate", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); - - // 每周统计数据(秒级精度) - key.SetValue("WeeklyLaunchCount", stats.WeeklyLaunchCount); - key.SetValue("WeeklyUsageSeconds", stats.WeeklyUsageSeconds); - key.SetValue("LastWeekUsageSeconds", stats.LastWeekUsageSeconds); - - // 兼容性:分钟精度数据 - key.SetValue("WeeklyUsageMinutes", stats.WeeklyUsageMinutes); - key.SetValue("LastWeekUsageMinutes", stats.LastWeekUsageMinutes); - - key.SetValue("WeekStartDate", stats.WeekStartDate.ToString("yyyy-MM-dd")); - key.SetValue("LastWeekLaunchCount", stats.LastWeekLaunchCount); - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 使用统计已保存到主注册表 - 总启动: {stats.LaunchCount}次, 本周启动: {stats.WeeklyLaunchCount}次, " + - // $"总时长: {FormatDuration(stats.TotalUsageSeconds)}, 本周时长: {FormatDuration(stats.WeeklyUsageSeconds)}"); - } - else - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 创建主注册表键失败", LogHelper.LogType.Error); + encryptedData[i] = (byte)(data[i] ^ keyBytes[i % keyBytes.Length]); } + + // 添加SHA256校验和 + byte[] checksum = sha256.ComputeHash(data); + byte[] finalData = new byte[checksum.Length + encryptedData.Length]; + checksum.CopyTo(finalData, 0); + encryptedData.CopyTo(finalData, checksum.Length); + + File.WriteAllBytes(filePath, finalData); + + LogHelper.WriteLogToFile($"DeviceIdentifier | 加密使用统计已保存到: {filePath}"); } } catch (Exception ex) { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 保存使用统计到主注册表失败: {ex.Message}", LogHelper.LogType.Error); + LogHelper.WriteLogToFile($"DeviceIdentifier | 保存使用统计到文件失败 ({filePath}): {ex.Message}", LogHelper.LogType.Error); } } /// - /// 保存使用统计到多个注册表位置(强化保护) - /// - private static void SaveUsageStatsToMultipleRegistryLocations(UsageStats stats) - { - var registryPaths = new[] - { - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 开始保存使用统计到{registryPaths.Length}个备用注册表位置"); - var successCount = 0; - - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.CreateSubKey(path)) - { - if (key != null) - { - // 使用编码的键名来隐藏数据(秒级精度) - key.SetValue("LC", stats.LaunchCount); // LaunchCount - - // 秒级精度数据 - key.SetValue("TUS", stats.TotalUsageSeconds); // TotalUsageSeconds - key.SetValue("ASS", stats.AverageSessionSeconds); // AverageSessionSeconds - - // 兼容性:分钟精度数据 - key.SetValue("TUM", stats.TotalUsageMinutes); // TotalUsageMinutes - key.SetValue("ASM", stats.AverageSessionMinutes); // AverageSessionMinutes - - key.SetValue("LLT", stats.LastLaunchTime.ToBinary()); // LastLaunchTime - key.SetValue("UP", (int)stats.UpdatePriority); // UpdatePriority - key.SetValue("UF", (int)stats.UsageFrequency); // UsageFrequency - key.SetValue("DH", stats.DataHash ?? ""); // DataHash - key.SetValue("LU", DateTime.Now.ToBinary()); // LastUpdate - - // 每周统计数据(秒级精度) - key.SetValue("WLC", stats.WeeklyLaunchCount); // WeeklyLaunchCount - key.SetValue("WUS", stats.WeeklyUsageSeconds); // WeeklyUsageSeconds - key.SetValue("LWUS", stats.LastWeekUsageSeconds); // LastWeekUsageSeconds - - // 兼容性:分钟精度数据 - key.SetValue("WUM", stats.WeeklyUsageMinutes); // WeeklyUsageMinutes - key.SetValue("LWUM", stats.LastWeekUsageMinutes); // LastWeekUsageMinutes - - key.SetValue("WSD", stats.WeekStartDate.ToBinary()); // WeekStartDate - key.SetValue("LWLC", stats.LastWeekLaunchCount); // LastWeekLaunchCount - - successCount++; - // LogHelper.WriteLogToFile($"DeviceIdentifier | 成功保存到备用注册表位置: {path}"); - } - else - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 创建备用注册表键失败: {path}", LogHelper.LogType.Error); - } - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 保存到备用注册表位置失败 ({path}): {ex.Message}", LogHelper.LogType.Error); - } - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 备用注册表保存完成: {successCount}/{registryPaths.Length} 成功"); - } - - /// - /// 记录更新检查时间(同时执行数据保护检查) + /// 记录更新检查时间 /// public static void RecordUpdateCheck() { @@ -1847,14 +1059,7 @@ namespace Ink_Canvas.Helpers { var stats = LoadUsageStats(); stats.LastUpdateCheck = DateTime.Now; - stats.UpdateDataHash(); SaveUsageStats(stats); - - // 定期执行数据保护检查(每10次更新检查执行一次) - if (stats.LaunchCount % 10 == 0) - { - PerformUsageDataProtectionCheck(); - } } } catch (Exception ex) @@ -1864,139 +1069,130 @@ namespace Ink_Canvas.Helpers } /// - /// 执行使用频率数据保护检查和自动修复 + /// 验证使用统计数据的完整性 /// - public static bool PerformUsageDataProtectionCheck() + public static bool ValidateUsageStatsIntegrity() { try { - lock (fileLock) + // 检查主文件 + if (File.Exists(UsageStatsFilePath)) { - LogHelper.WriteLogToFile("DeviceIdentifier | 开始使用频率数据保护检查"); - - var issues = new List(); - var repaired = new List(); - var backupPaths = new[] + var mainStats = LoadUsageStatsFromFile(UsageStatsFilePath); + if (mainStats != null && mainStats.DeviceId == DeviceId) { - new { Path = UsageStatsFilePath, Name = "主文件" }, - new { Path = BackupUsageStatsPath, Name = "第一备份" }, - new { Path = SecondaryUsageBackupPath, Name = "第二备份" }, - new { Path = TertiaryUsageBackupPath, Name = "第三备份" }, - new { Path = QuaternaryUsageBackupPath, Name = "第四备份" } - }; - - // 检查所有备份文件 - UsageStats validStats = null; - var missingFiles = new List(); - - foreach (var backup in backupPaths) - { - if (!File.Exists(backup.Path)) - { - issues.Add($"{backup.Name}丢失"); - missingFiles.Add(backup.Path); - } - else - { - var stats = LoadUsageStatsFromFile(backup.Path); - if (stats != null && stats.VerifyDataIntegrity() && validStats == null) - { - validStats = stats; - } - } + LogHelper.WriteLogToFile("DeviceIdentifier | 主文件数据完整性验证通过"); + return true; } - - // 如果找到有效数据,修复丢失的文件 - if (validStats != null && missingFiles.Count > 0) - { - foreach (var missingFile in missingFiles) - { - SaveUsageStatsToFile(missingFile, validStats); - repaired.Add($"恢复文件: {Path.GetFileName(missingFile)}"); - } - } - - // 检查注册表备份 - var registryPaths = new[] - { - @"Software\ICC\DeviceInfo", - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - var missingRegistryBackups = 0; - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(path)) - { - if (key == null) missingRegistryBackups++; - } - } - catch - { - missingRegistryBackups++; - } - } - - if (missingRegistryBackups > 0) - { - issues.Add($"{missingRegistryBackups}个注册表备份丢失"); - if (validStats != null) - { - SaveUsageStatsToMultipleRegistryLocations(validStats); - repaired.Add("重建注册表备份"); - } - } - - // 如果没有找到任何有效数据,尝试从注册表恢复 - if (validStats == null) - { - validStats = LoadUsageStatsFromRegistry(); - if (validStats == null) - { - validStats = LoadUsageStatsFromMultipleRegistryLocations(); - } - - if (validStats != null) - { - SaveUsageStatsToAllLocations(validStats); - repaired.Add("从注册表完全恢复数据"); - } - else - { - // 最后手段:强制重建 - ForceRebuildUsageDataBackups(); - repaired.Add("强制重建所有备份"); - } - } - - // 记录检查结果 - if (issues.Count > 0) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 使用频率数据保护检查发现问题: {string.Join(", ", issues)}", LogHelper.LogType.Warning); - } - - if (repaired.Count > 0) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 使用频率数据保护修复: {string.Join(", ", repaired)}"); - } - - var protectionScore = CalculateUsageDataProtectionScore(); - LogHelper.WriteLogToFile($"DeviceIdentifier | 使用频率数据保护检查完成 - 问题: {issues.Count}, 修复: {repaired.Count}, 保护强度: {protectionScore}/100"); - - return protectionScore >= 80; } + + // 检查备份文件 + if (File.Exists(UsageStatsBackupPath)) + { + var backupStats = LoadUsageStatsFromFile(UsageStatsBackupPath); + if (backupStats != null && backupStats.DeviceId == DeviceId) + { + LogHelper.WriteLogToFile("DeviceIdentifier | 备份文件数据完整性验证通过"); + return true; + } + } + + LogHelper.WriteLogToFile("DeviceIdentifier | 数据完整性验证失败", LogHelper.LogType.Warning); + return false; } catch (Exception ex) { - LogHelper.WriteLogToFile($"DeviceIdentifier | 使用频率数据保护检查失败: {ex.Message}", LogHelper.LogType.Error); + LogHelper.WriteLogToFile($"DeviceIdentifier | 数据完整性验证失败: {ex.Message}", LogHelper.LogType.Error); return false; } } + /// + /// 从备份文件恢复使用统计数据 + /// + public static bool RestoreUsageStatsFromBackup() + { + try + { + if (File.Exists(UsageStatsBackupPath)) + { + var backupStats = LoadUsageStatsFromFile(UsageStatsBackupPath); + if (backupStats != null && backupStats.DeviceId == DeviceId) + { + // 保存到主文件 + SaveUsageStatsToFile(UsageStatsFilePath, backupStats); + LogHelper.WriteLogToFile("DeviceIdentifier | 从备份文件成功恢复使用统计数据"); + return true; + } + } + + LogHelper.WriteLogToFile("DeviceIdentifier | 备份文件不存在或损坏,无法恢复", LogHelper.LogType.Warning); + return false; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 从备份文件恢复失败: {ex.Message}", LogHelper.LogType.Error); + return false; + } + } + + /// + /// 获取使用统计文件状态信息 + /// + public static string GetUsageStatsFileStatus() + { + try + { + var status = new List(); + + // 检查主文件 + if (File.Exists(UsageStatsFilePath)) + { + var fileInfo = new FileInfo(UsageStatsFilePath); + var mainStats = LoadUsageStatsFromFile(UsageStatsFilePath); + if (mainStats != null && mainStats.DeviceId == DeviceId) + { + status.Add($"主文件: 正常 ({fileInfo.Length} 字节, 修改时间: {fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss})"); + } + else + { + status.Add($"主文件: 损坏 ({fileInfo.Length} 字节)"); + } + } + else + { + status.Add("主文件: 不存在"); + } + + // 检查备份文件 + if (File.Exists(UsageStatsBackupPath)) + { + var fileInfo = new FileInfo(UsageStatsBackupPath); + var backupStats = LoadUsageStatsFromFile(UsageStatsBackupPath); + if (backupStats != null && backupStats.DeviceId == DeviceId) + { + status.Add($"备份文件: 正常 ({fileInfo.Length} 字节, 修改时间: {fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss})"); + } + else + { + status.Add($"备份文件: 损坏 ({fileInfo.Length} 字节)"); + } + } + else + { + status.Add("备份文件: 不存在"); + } + + return string.Join("\n", status); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"DeviceIdentifier | 获取文件状态失败: {ex.Message}", LogHelper.LogType.Error); + return "获取文件状态失败"; + } + } + + /// /// 根据优先级决定是否应该推送更新(仅适用于自动更新,版本修复功能不受影响) /// @@ -2279,7 +1475,8 @@ namespace Ink_Canvas.Helpers $"使用频率: {frequency}\n" + $"更新优先级: {priority}\n" + $"最后使用: {daysSinceLastUse:F1}天前\n" + - $"用户类型: {GetUserTypeDescription(stats)}"; + $"用户类型: {GetUserTypeDescription(stats)}\n\n" + + $"文件状态:\n{GetUsageStatsFileStatus()}"; } catch (Exception ex) { @@ -2310,461 +1507,19 @@ namespace Ink_Canvas.Helpers return descriptions.Count > 0 ? string.Join(", ", descriptions) : "普通用户"; } - /// - /// 数据自检和修复 - /// - public static bool PerformDataIntegrityCheck() - { - try - { - lock (fileLock) - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 开始数据完整性检查"); - - var issues = new List(); - var repaired = new List(); - - // 检查设备ID文件 - if (!File.Exists(DeviceIdFilePath)) - { - issues.Add("主设备ID文件丢失"); - if (File.Exists(BackupDeviceIdPath)) - { - var backupId = LoadDeviceIdFromFile(BackupDeviceIdPath); - if (!string.IsNullOrEmpty(backupId)) - { - SaveDeviceIdToFile(DeviceIdFilePath, backupId); - repaired.Add("从备份恢复主设备ID文件"); - } - } - } - - // 检查备份设备ID文件 - if (!File.Exists(BackupDeviceIdPath)) - { - issues.Add("备份设备ID文件丢失"); - var mainId = LoadDeviceIdFromFile(DeviceIdFilePath); - if (!string.IsNullOrEmpty(mainId)) - { - SaveDeviceIdToFile(BackupDeviceIdPath, mainId); - repaired.Add("重建备份设备ID文件"); - } - } - - // 检查使用统计文件 - if (!File.Exists(UsageStatsFilePath)) - { - issues.Add("主使用统计文件丢失"); - var backupStatsForRestore = LoadUsageStatsFromFile(BackupUsageStatsPath); - if (backupStatsForRestore != null) - { - SaveUsageStatsToFile(UsageStatsFilePath, backupStatsForRestore); - repaired.Add("从备份恢复主使用统计文件"); - } - } - - // 检查备份使用统计文件 - if (!File.Exists(BackupUsageStatsPath)) - { - issues.Add("备份使用统计文件丢失"); - var mainStatsForBackup = LoadUsageStatsFromFile(UsageStatsFilePath); - if (mainStatsForBackup != null) - { - SaveUsageStatsToFile(BackupUsageStatsPath, mainStatsForBackup); - repaired.Add("重建备份使用统计文件"); - } - } - - // 验证数据一致性 - var mainStats = LoadUsageStatsFromFile(UsageStatsFilePath); - var backupStats = LoadUsageStatsFromFile(BackupUsageStatsPath); - - if (mainStats != null && backupStats != null) - { - if (mainStats.LaunchCount != backupStats.LaunchCount || - mainStats.TotalUsageMinutes != backupStats.TotalUsageMinutes) - { - issues.Add("主备份数据不一致"); - // 使用最新的数据 - var newerStats = mainStats.LastModified > backupStats.LastModified ? mainStats : backupStats; - SaveUsageStatsToAllLocations(newerStats); - repaired.Add("同步主备份数据"); - } - } - - // 记录检查结果 - if (issues.Count > 0) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 发现问题: {string.Join(", ", issues)}", LogHelper.LogType.Warning); - } - - if (repaired.Count > 0) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 已修复: {string.Join(", ", repaired)}"); - } - - // LogHelper.WriteLogToFile($"DeviceIdentifier | 数据完整性检查完成 - 问题: {issues.Count}, 修复: {repaired.Count}"); - return issues.Count == 0 || repaired.Count > 0; - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 数据完整性检查失败: {ex.Message}", LogHelper.LogType.Error); - return false; - } - } - - /// - /// 获取使用频率数据保护状态摘要(强化版本) - /// - public static string GetUsageDataProtectionSummary() - { - try - { - var summary = new StringBuilder(); - summary.AppendLine("使用频率数据保护状态摘要:"); - - // 检查主要文件 - summary.AppendLine($"主使用统计文件: {(File.Exists(UsageStatsFilePath) ? "✓" : "✗")}"); - summary.AppendLine($"第一备份文件: {(File.Exists(BackupUsageStatsPath) ? "✓" : "✗")}"); - - // 检查多重隐藏备份 - summary.AppendLine($"第二备份文件: {(File.Exists(SecondaryUsageBackupPath) ? "✓" : "✗")}"); - summary.AppendLine($"第三备份文件: {(File.Exists(TertiaryUsageBackupPath) ? "✓" : "✗")}"); - summary.AppendLine($"第四备份文件: {(File.Exists(QuaternaryUsageBackupPath) ? "✓" : "✗")}"); - - // 检查注册表备份 - var registryBackups = 0; - var registryPaths = new[] - { - @"Software\ICC\DeviceInfo", - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(path)) - { - if (key != null) registryBackups++; - } - } - catch { } - } - - summary.AppendLine($"注册表备份位置: {registryBackups}/4 ✓"); - - // 检查数据完整性和可恢复性 - var stats = LoadUsageStats(); - if (stats != null) - { - summary.AppendLine($"数据完整性: {(stats.VerifyDataIntegrity() ? "✓" : "✗")}"); - summary.AppendLine($"总启动次数: {stats.LaunchCount}"); - summary.AppendLine($"总使用时长: {FormatDuration(stats.TotalUsageSeconds)}"); - summary.AppendLine($"本周启动次数: {stats.WeeklyLaunchCount}"); - summary.AppendLine($"本周使用时长: {FormatDuration(stats.WeeklyUsageSeconds)}"); - summary.AppendLine($"上周启动次数: {stats.LastWeekLaunchCount}"); - summary.AppendLine($"上周使用时长: {FormatDuration(stats.LastWeekUsageSeconds)}"); - summary.AppendLine($"本周开始日期: {(stats.WeekStartDate != DateTime.MinValue ? stats.WeekStartDate.ToString("yyyy-MM-dd") : "未设置")}"); - summary.AppendLine($"使用频率: {stats.UsageFrequency}"); - summary.AppendLine($"更新优先级: {stats.UpdatePriority}"); - summary.AppendLine($"最后修改: {stats.LastModified:yyyy-MM-dd HH:mm:ss}"); - } - - // 计算保护强度评分 - var protectionScore = CalculateUsageDataProtectionScore(); - summary.AppendLine($"保护强度评分: {protectionScore}/100"); - - return summary.ToString(); - } - catch (Exception ex) - { - return $"获取使用频率数据保护状态失败: {ex.Message}"; - } - } - - /// - /// 计算使用频率数据保护强度评分 - /// - private static int CalculateUsageDataProtectionScore() - { - var score = 0; - - try - { - // 文件备份评分(50分) - if (File.Exists(UsageStatsFilePath)) score += 15; - if (File.Exists(BackupUsageStatsPath)) score += 10; - if (File.Exists(SecondaryUsageBackupPath)) score += 8; - if (File.Exists(TertiaryUsageBackupPath)) score += 8; - if (File.Exists(QuaternaryUsageBackupPath)) score += 9; - - // 注册表备份评分(30分) - var registryPaths = new[] - { - @"Software\ICC\DeviceInfo", - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(path)) - { - if (key != null) score += 7; - } - } - catch { } - } - - // 数据完整性评分(20分) - var stats = LoadUsageStats(); - if (stats != null) - { - if (!string.IsNullOrEmpty(stats.DataHash)) score += 10; - if (stats.VerifyDataIntegrity()) score += 10; - } - } - catch { } - - return Math.Min(100, score); - } - - /// - /// 强制重建所有使用频率数据备份 - /// - public static bool ForceRebuildUsageDataBackups() - { - try - { - lock (fileLock) - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 开始强制重建使用频率数据备份"); - - var stats = LoadUsageStats(); - if (stats == null) - { - // 如果无法加载任何数据,创建基础数据 - stats = new UsageStats - { - DeviceId = DeviceId, - LastLaunchTime = DateTime.Now, - LaunchCount = 1, - TotalUsageMinutes = 0, - AverageSessionMinutes = 0, - LastUpdateCheck = DateTime.MinValue, - UpdatePriority = UpdatePriority.Medium, - UsageFrequency = UsageFrequency.Medium - }; - stats.UpdateDataHash(); - LogHelper.WriteLogToFile("DeviceIdentifier | 创建新的基础使用数据"); - } - - // 强制保存到所有位置 - SaveUsageStatsToAllLocations(stats); - - // 验证重建结果 - var protectionScore = CalculateUsageDataProtectionScore(); - // LogHelper.WriteLogToFile($"DeviceIdentifier | 使用频率数据备份重建完成,保护强度: {protectionScore}/100"); - - return protectionScore >= 80; // 80分以上认为重建成功 - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 强制重建使用频率数据备份失败: {ex.Message}", LogHelper.LogType.Error); - return false; - } - } - - /// - /// 获取数据保护状态摘要(保持向后兼容) - /// - public static string GetDataProtectionSummary() - { - return GetUsageDataProtectionSummary(); - } - - - - /// - /// 强制执行一次完整的数据保存操作(包括注册表) - /// - public static bool ForceCompleteDataSave() - { - try - { - lock (fileLock) - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 开始强制完整数据保存"); - - // 保存设备ID到所有位置 - SaveDeviceIdToAllLocations(DeviceId); - - // 加载并保存使用统计到所有位置 - var stats = LoadUsageStats(); - if (stats != null) - { - stats.UpdateDataHash(); - SaveUsageStatsToAllLocations(stats); - - // 验证注册表保存是否成功 - var verificationResult = VerifyRegistryData(); - // LogHelper.WriteLogToFile($"DeviceIdentifier | 注册表数据验证结果: {verificationResult}"); - - // LogHelper.WriteLogToFile("DeviceIdentifier | 强制完整数据保存完成"); - return true; - } - - // LogHelper.WriteLogToFile("DeviceIdentifier | 强制完整数据保存失败: 无法加载使用统计", LogHelper.LogType.Error); - return false; - } - } - catch (Exception ex) - { - // LogHelper.WriteLogToFile($"DeviceIdentifier | 强制完整数据保存失败: {ex.Message}", LogHelper.LogType.Error); - return false; - } - } - - /// - /// 验证注册表中的数据是否存在 - /// - public static string VerifyRegistryData() - { - var results = new StringBuilder(); - results.AppendLine("注册表数据验证结果:"); - - try - { - // 验证主注册表位置 - try - { - using (var key = Registry.CurrentUser.OpenSubKey(@"Software\ICC\DeviceInfo")) - { - if (key != null) - { - var deviceId = key.GetValue("DeviceId") as string; - var launchCount = key.GetValue("LaunchCount"); - var totalMinutes = key.GetValue("TotalUsageMinutes"); - var lastUpdate = key.GetValue("LastUpdate") as string; - - results.AppendLine("✓ 主注册表位置存在"); - results.AppendLine($" 设备ID: {deviceId ?? "未找到"}"); - results.AppendLine($" 启动次数: {launchCount ?? "未找到"}"); - results.AppendLine($" 使用时长: {totalMinutes ?? "未找到"}分钟"); - results.AppendLine($" 最后更新: {lastUpdate ?? "未找到"}"); - } - else - { - results.AppendLine("✗ 主注册表位置不存在"); - } - } - } - catch (Exception ex) - { - results.AppendLine($"✗ 主注册表位置访问失败: {ex.Message}"); - } - - // 验证备用注册表位置 - var registryPaths = new[] - { - @"Software\Microsoft\Windows\CurrentVersion\ICC", - @"Software\Classes\.icc\UsageData", - @"Software\ICC\Config\Usage" - }; - - foreach (var path in registryPaths) - { - try - { - using (var key = Registry.CurrentUser.OpenSubKey(path)) - { - if (key != null) - { - var launchCount = key.GetValue("LC"); - var totalMinutes = key.GetValue("TUM"); - var lastUpdate = key.GetValue("LU"); - - results.AppendLine($"✓ 备用注册表位置存在: {path}"); - results.AppendLine($" 启动次数: {launchCount ?? "未找到"}"); - results.AppendLine($" 使用时长: {totalMinutes ?? "未找到"}"); - results.AppendLine($" 最后更新: {(lastUpdate != null ? DateTime.FromBinary(Convert.ToInt64(lastUpdate)).ToString("yyyy-MM-dd HH:mm:ss") : "未找到")}"); - } - else - { - results.AppendLine($"✗ 备用注册表位置不存在: {path}"); - } - } - } - catch (Exception ex) - { - results.AppendLine($"✗ 备用注册表位置访问失败 ({path}): {ex.Message}"); - } - } - - return results.ToString(); - } - catch (Exception ex) - { - return $"注册表数据验证失败: {ex.Message}"; - } - } - - /// - /// 立即执行一次数据保存并验证注册表写入 - /// - public static string SaveAndVerifyRegistryData() - { - try - { - // LogHelper.WriteLogToFile("DeviceIdentifier | 开始保存并验证注册表数据"); - - // 强制保存数据 - var saveSuccess = ForceCompleteDataSave(); - - // 验证注册表数据 - var verificationResult = VerifyRegistryData(); - - var result = $"保存操作: {(saveSuccess ? "成功" : "失败")}\n\n{verificationResult}"; - - // LogHelper.WriteLogToFile("DeviceIdentifier | 保存并验证注册表数据完成"); - return result; - } - catch (Exception ex) - { - var errorMsg = $"保存并验证注册表数据失败: {ex.Message}"; - LogHelper.WriteLogToFile($"DeviceIdentifier | {errorMsg}", LogHelper.LogType.Error); - return errorMsg; - } - } /// /// 关机时保存使用时间数据 /// public static void SaveUsageStatsOnShutdown() { - // 使用超时锁防止死锁 - if (!Monitor.TryEnter(fileLock, TimeSpan.FromSeconds(30))) - { - LogHelper.WriteLogToFile("DeviceIdentifier | 关机保存超时,使用备用保存策略", LogHelper.LogType.Warning); - SaveUsageStatsOnShutdownFallback(); - return; - } - try { LogHelper.WriteLogToFile("DeviceIdentifier | 开始关机时保存使用时间数据", LogHelper.LogType.Info); - // 1. 加载现有使用统计数据(多重恢复策略) - UsageStats stats = LoadUsageStatsWithFallback(); + // 1. 加载现有使用统计数据 + var stats = LoadUsageStats(); if (stats == null) { stats = new UsageStats { DeviceId = DeviceId }; @@ -2788,261 +1543,16 @@ namespace Ink_Canvas.Helpers stats.AverageSessionSeconds = stats.TotalUsageSeconds / (double)Math.Max(1, stats.LaunchCount); stats.LastLaunchTime = DateTime.Now; - // 更新数据哈希值 - stats.UpdateDataHash(); - - // 4. 多重保存策略 - 确保数据不丢失 - var saveResults = new List(); + // 4. 保存数据 + SaveUsageStats(stats); - // 4.1 保存到所有文件位置 - saveResults.Add(SaveUsageStatsToAllFileLocations(stats)); - - // 4.2 保存到所有注册表位置 - saveResults.Add(SaveUsageStatsToAllRegistryLocations(stats)); - - // 4.3 保存到内存缓存(作为最后防线) - SaveUsageStatsToMemoryCache(stats); - - // 4.4 强制刷新文件系统缓存 - ForceFlushFileSystem(); - - // 4.5 验证保存结果 - var verificationResult = VerifyDataSaveResults(stats, saveResults); - - LogHelper.WriteLogToFile($"DeviceIdentifier | 关机保存完成,验证结果: {verificationResult}", LogHelper.LogType.Info); + LogHelper.WriteLogToFile("DeviceIdentifier | 关机保存完成", LogHelper.LogType.Info); } catch (Exception ex) { LogHelper.WriteLogToFile($"DeviceIdentifier | 关机时保存使用时间数据失败: {ex.Message}", LogHelper.LogType.Error); - - // 即使主保存失败,也要尝试备用保存 - try - { - SaveUsageStatsOnShutdownFallback(); - } - catch (Exception fallbackEx) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 备用保存也失败: {fallbackEx.Message}", LogHelper.LogType.Error); - } - } - finally - { - Monitor.Exit(fileLock); } } - - /// - /// 关机保存的备用策略 - /// - private static void SaveUsageStatsOnShutdownFallback() - { - try - { - LogHelper.WriteLogToFile("DeviceIdentifier | 执行关机保存备用策略", LogHelper.LogType.Warning); - - // 使用最基本的保存方式 - var stats = new UsageStats { DeviceId = DeviceId }; - stats.TotalUsageSeconds = 1; // 最小记录 - stats.LaunchCount = 1; - stats.LastLaunchTime = DateTime.Now; - - // 只保存到最可靠的位置 - SaveUsageStatsToFile(BackupUsageStatsPath, stats); - SaveUsageStatsToRegistry(stats); - - LogHelper.WriteLogToFile("DeviceIdentifier | 备用策略执行完成", LogHelper.LogType.Info); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 备用策略执行失败: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 加载使用统计数据(带多重恢复策略) - /// - private static UsageStats LoadUsageStatsWithFallback() - { - try - { - // 1. 尝试从主文件加载 - var stats = LoadUsageStats(); - if (stats != null) return stats; - - // 2. 尝试从备份文件加载 - stats = LoadUsageStatsFromFile(BackupUsageStatsPath); - if (stats != null) return stats; - - // 3. 尝试从其他备份位置加载 - var backupPaths = new[] { SecondaryUsageBackupPath, TertiaryUsageBackupPath, QuaternaryUsageBackupPath }; - foreach (var path in backupPaths) - { - stats = LoadUsageStatsFromFile(path); - if (stats != null) return stats; - } - - // 4. 尝试从注册表恢复 - stats = LoadUsageStatsFromRegistry(); - if (stats != null) return stats; - - return null; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 多重恢复加载失败: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 保存使用统计到所有文件位置 - /// - private static string SaveUsageStatsToAllFileLocations(UsageStats stats) - { - var results = new List(); - var filePaths = new[] - { - UsageStatsFilePath, - BackupUsageStatsPath, - SecondaryUsageBackupPath, - TertiaryUsageBackupPath, - QuaternaryUsageBackupPath - }; - - foreach (var filePath in filePaths) - { - try - { - SaveUsageStatsToFile(filePath, stats); - results.Add($"✓ {Path.GetFileName(filePath)}"); - } - catch (Exception ex) - { - results.Add($"✗ {Path.GetFileName(filePath)}: {ex.Message}"); - } - } - - return string.Join("\n", results); - } - - /// - /// 保存使用统计到所有注册表位置 - /// - private static string SaveUsageStatsToAllRegistryLocations(UsageStats stats) - { - var results = new List(); - - try - { - // 主注册表位置 - SaveUsageStatsToRegistry(stats); - results.Add("✓ 主注册表位置"); - } - catch (Exception ex) - { - results.Add($"✗ 主注册表位置: {ex.Message}"); - } - - try - { - // 备用注册表位置 - SaveUsageStatsToMultipleRegistryLocations(stats); - results.Add("✓ 备用注册表位置"); - } - catch (Exception ex) - { - results.Add($"✗ 备用注册表位置: {ex.Message}"); - } - - return string.Join("\n", results); - } - - /// - /// 保存使用统计到内存缓存 - /// - private static void SaveUsageStatsToMemoryCache(UsageStats stats) - { - try - { - // 将数据保存到静态变量作为内存备份 - _cachedUsageStats = stats; - LogHelper.WriteLogToFile("DeviceIdentifier | 数据已保存到内存缓存", LogHelper.LogType.Info); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 保存到内存缓存失败: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 强制刷新文件系统缓存 - /// - private static void ForceFlushFileSystem() - { - try - { - // 强制刷新所有相关目录 - var directories = new[] - { - Path.GetDirectoryName(UsageStatsFilePath), - Path.GetDirectoryName(BackupUsageStatsPath), - Path.GetDirectoryName(SecondaryUsageBackupPath), - Path.GetDirectoryName(TertiaryUsageBackupPath), - Path.GetDirectoryName(QuaternaryUsageBackupPath) - }; - - foreach (var dir in directories.Where(d => !string.IsNullOrEmpty(d) && Directory.Exists(d))) - { - try - { - // 创建临时文件来强制刷新 - var tempFile = Path.Combine(dir, ".flush.tmp"); - File.WriteAllText(tempFile, DateTime.Now.ToString()); - File.Delete(tempFile); - } - catch { /* 忽略刷新错误 */ } - } - - LogHelper.WriteLogToFile("DeviceIdentifier | 文件系统缓存刷新完成", LogHelper.LogType.Info); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"DeviceIdentifier | 文件系统缓存刷新失败: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 验证数据保存结果 - /// - private static string VerifyDataSaveResults(UsageStats stats, List saveResults) - { - var verification = new StringBuilder(); - verification.AppendLine("数据保存验证结果:"); - verification.AppendLine(string.Join("\n", saveResults)); - - // 验证关键数据是否保存成功 - try - { - var savedStats = LoadUsageStats(); - if (savedStats != null && savedStats.DeviceId == stats.DeviceId) - { - verification.AppendLine("✓ 主数据文件验证成功"); - } - else - { - verification.AppendLine("✗ 主数据文件验证失败"); - } - } - catch (Exception ex) - { - verification.AppendLine($"✗ 主数据文件验证异常: {ex.Message}"); - } - - return verification.ToString(); - } - - // 内存缓存变量 - private static UsageStats _cachedUsageStats; } }