提交记录修改Core/Librarys/SQLite/SQLiteBuilder.cs+225 −39看文件
修改Core/Librarys/SQLite/StatisticContext.cs+2 −1看文件
修改Core/Servicers/Instances/Main.cs+69 −12看文件
修改UI/App.xaml.cs+31 −5看文件
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Data.SQLite; |
| 4 | 新增:using System.Diagnostics; | |
| 4 | 5 | using System.IO; |
| 5 | 6 | using System.Linq; |
| 6 | 7 | using System.Reflection; |
| @@ -36,15 +37,26 @@ namespace Core.Librarys.SQLite | ||
| 36 | 37 | /// 列名 |
| 37 | 38 | /// </summary> |
| 38 | 39 | public string Name { get; set; } |
| 39 | 删除: public string Type { get; set; } | |
| 40 | 新增: public DbType Type { get; set; } | |
| 40 | 41 | public bool PK { get; set; } |
| 41 | 删除: public bool NotNull { get { return !PK; } } | |
| 42 | 新增: //public bool NotNull { get { return !PK; } } | |
| 42 | 43 | } |
| 44 | 新增: | |
| 45 | 新增: public enum DbType | |
| 46 | 新增: { | |
| 47 | 新增: INTEGER, | |
| 48 | 新增: datetime, | |
| 49 | 新增: nvarchar, | |
| 50 | 新增: @int | |
| 51 | 新增: } | |
| 52 | 新增: | |
| 43 | 53 | /// <summary> |
| 44 | 54 | ///handle sqlite code first |
| 45 | 55 | /// </summary> |
| 46 | 56 | public class SQLiteBuilder |
| 47 | 57 | { |
| 58 | 新增: public static bool IsSelfChecking = true; | |
| 59 | 新增: | |
| 48 | 60 | private System.Data.Entity.Infrastructure.DbModel model; |
| 49 | 61 | /// <summary> |
| 50 | 62 | /// 连接字符串 |
| @@ -54,6 +66,11 @@ namespace Core.Librarys.SQLite | ||
| 54 | 66 | /// 数据库版本文件 |
| 55 | 67 | /// </summary> |
| 56 | 68 | private string versionFile; |
| 69 | 新增: | |
| 70 | 新增: /// <summary> | |
| 71 | 新增: /// 数据库文件路径 | |
| 72 | 新增: /// </summary> | |
| 73 | 新增: private string dbFile; | |
| 57 | 74 | /// <summary> |
| 58 | 75 | /// 数据模型 |
| 59 | 76 | /// </summary> |
| @@ -71,62 +88,210 @@ namespace Core.Librarys.SQLite | ||
| 71 | 88 | |
| 72 | 89 | providerManifest = model.ProviderManifest; |
| 73 | 90 | |
| 74 | 删除: versionFile = connstr.Split('=')[1] + ".version"; | |
| 91 | 新增: dbFile = connstr.Split('=')[1]; | |
| 92 | 新增: | |
| 93 | 新增: versionFile = $"{dbFile}.version"; | |
| 94 | 新增: | |
| 75 | 95 | } |
| 76 | 96 | } |
| 77 | 97 | |
| 78 | 删除: public void Handle() | |
| 98 | 新增: /// <summary> | |
| 99 | 新增: /// 执行数据库自检 | |
| 100 | 新增: /// </summary> | |
| 101 | 新增: public bool SelfCheck() | |
| 79 | 102 | { |
| 80 | 103 | if (IsHandleDb()) |
| 81 | 104 | { |
| 82 | 删除: HandleTable(); | |
| 105 | 新增: bool res = HandleTable(); | |
| 106 | 新增: | |
| 107 | 新增: IsSelfChecking = false; | |
| 108 | 新增: | |
| 109 | 新增: return res; | |
| 83 | 110 | } |
| 111 | 新增: | |
| 112 | 新增: IsSelfChecking = false; | |
| 113 | 新增: | |
| 114 | 新增: return true; | |
| 84 | 115 | } |
| 85 | 116 | |
| 86 | 117 | /// <summary> |
| 87 | 删除: /// 处理表变化(仅处理新增表、新增表字段。不处理表名更改、列名更改、删除) | |
| 118 | 新增: /// 处理表变化(仅处理新增表、新增表字段、表结构变化) | |
| 88 | 119 | /// </summary> |
| 89 | 删除: private void HandleTable() | |
| 120 | 新增: private bool HandleTable() | |
| 90 | 121 | { |
| 91 | 删除: var modelInfos = GetModelInfos(); | |
| 122 | 新增: try | |
| 123 | 新增: { | |
| 124 | 新增: // 处理前先复制一份数据库文件以防万一 | |
| 125 | 新增: string dir = Path.Combine(Path.GetDirectoryName(dbFile), "backup"); | |
| 126 | 新增: string backupName = Path.Combine(dir, $"data.handle.backup"); | |
| 127 | 新增: if (!Directory.Exists(dir)) | |
| 128 | 新增: { | |
| 129 | 新增: Directory.CreateDirectory(dir); | |
| 130 | 新增: } | |
| 131 | 新增: if (File.Exists(backupName)) | |
| 132 | 新增: { | |
| 133 | 新增: File.Delete(backupName); | |
| 134 | 新增: } | |
| 135 | 新增: File.Copy(dbFile, backupName); | |
| 92 | 136 | |
| 93 | 删除: var modelInfosDb = GetModelInfosForDb(); | |
| 137 | 新增: var modelInfos = GetModelInfos(); | |
| 94 | 138 | |
| 95 | 删除: foreach (var model in modelInfos) | |
| 96 | 删除: { | |
| 97 | 删除: //表名 | |
| 98 | 删除: string tableName = model.TableName; | |
| 139 | 新增: var modelInfosDb = GetModelInfosForDb(); | |
| 99 | 140 | |
| 100 | 删除: var modelInfoDb = modelInfosDb.Where(m => m.TableName == tableName); | |
| 101 | 删除: //判断表是否存在 | |
| 102 | 删除: if (modelInfoDb.Count() <= 0) | |
| 141 | 新增: foreach (var model in modelInfos) | |
| 103 | 142 | { |
| 104 | 删除: //不存在则重新创建表 | |
| 105 | 删除: string csql = GetCreateTableSQL(model); | |
| 106 | 删除: ExecuteNonQuery(csql); | |
| 143 | 新增: //表名 | |
| 144 | 新增: string tableName = model.TableName; | |
| 145 | 新增: | |
| 146 | 新增: var modelInfoDb = modelInfosDb.Where(m => m.TableName == tableName); | |
| 147 | 新增: //判断表是否存在 | |
| 148 | 新增: if (modelInfoDb.Count() <= 0) | |
| 149 | 新增: { | |
| 150 | 新增: //不存在则重新创建表 | |
| 151 | 新增: string csql = GetCreateTableSQL(model); | |
| 152 | 新增: ExecuteNonQuery(csql); | |
| 153 | 新增: } | |
| 154 | 新增: else | |
| 155 | 新增: { | |
| 156 | 新增: //存在则扫描新字段(*暂时不处理字段的属性变化,只处理新增) | |
| 157 | 新增: | |
| 158 | 新增: //对应的数据库模型信息 | |
| 159 | 新增: var modelDb = modelInfoDb.Single(); | |
| 160 | 新增: //查找差异属性 | |
| 161 | 新增: foreach (var item in model.Properties) | |
| 162 | 新增: { | |
| 163 | 新增: if (modelDb.Properties.Where(m => m.Name == item.Name).Count() <= 0) | |
| 164 | 新增: { | |
| 165 | 新增: string csql = GetCreateColumnSQL(tableName, item); | |
| 166 | 新增: ExecuteNonQuery(csql); | |
| 167 | 新增: } | |
| 168 | 新增: } | |
| 169 | 新增: | |
| 170 | 新增: } | |
| 171 | 新增: | |
| 107 | 172 | } |
| 108 | 删除: else | |
| 173 | 新增: | |
| 174 | 新增: HandleVersion1002Migrate(); | |
| 175 | 新增: | |
| 176 | 新增: | |
| 177 | 新增: // 处理表字段删除 | |
| 178 | 新增: foreach (var dbModel in modelInfosDb) | |
| 109 | 179 | { |
| 110 | 删除: //存在则扫描新字段(*暂时不处理字段的属性变化,只处理新增) | |
| 180 | 新增: // 表名 | |
| 181 | 新增: string tableName = dbModel.TableName; | |
| 182 | 新增: | |
| 183 | 新增: // 查找对应的实体模型 | |
| 184 | 新增: var model = modelInfos.Where(m => m.TableName == tableName).FirstOrDefault(); | |
| 111 | 185 | |
| 112 | 删除: //对应的数据库模型信息 | |
| 113 | 删除: var modelDb = modelInfoDb.Single(); | |
| 114 | 删除: //查找差异属性 | |
| 115 | 删除: foreach (var item in model.Properties) | |
| 186 | 新增: if (model == null) | |
| 187 | 新增: { | |
| 188 | 新增: // 已删除的模型就从数据库中删除 | |
| 189 | 新增: //ExecuteNonQuery($"DROP TABLE {tableName}");// 暂时不处理 | |
| 190 | 新增: } | |
| 191 | 新增: else | |
| 116 | 192 | { |
| 117 | 删除: if (modelDb.Properties.Where(m => m.Name == item.Name).Count() <= 0) | |
| 193 | 新增: // 遍历数据库表的属性 | |
| 194 | 新增: | |
| 195 | 新增: bool isDel = false; | |
| 196 | 新增: | |
| 197 | 新增: | |
| 198 | 新增: | |
| 199 | 新增: foreach (var dbItem in dbModel.Properties) | |
| 118 | 200 | { |
| 119 | 删除: string csql = GetCreateColumnSQL(tableName, item); | |
| 120 | 删除: ExecuteNonQuery(csql); | |
| 201 | 新增: // 判断实体模型是否有字段,没有的话需要重建表 | |
| 202 | 新增: if (!model.Properties.Where(m => m.Name == dbItem.Name).Any()) | |
| 203 | 新增: { | |
| 204 | 新增: isDel = true; | |
| 205 | 新增: break; | |
| 206 | 新增: } | |
| 207 | 新增: | |
| 208 | 新增: | |
| 209 | 新增: } | |
| 210 | 新增: if (isDel) | |
| 211 | 新增: { | |
| 212 | 新增: // 模型字段 | |
| 213 | 新增: string field = string.Join(",", model.Properties.Select(m => m.Name).ToArray()); | |
| 214 | 新增: | |
| 215 | 新增: // 临时表名 | |
| 216 | 新增: string tempName = $"{tableName}_temp_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; | |
| 217 | 新增: | |
| 218 | 新增: // 创建一个新表 | |
| 219 | 新增: ExecuteNonQuery(GetCreateTableSQL(model, tempName)); | |
| 220 | 新增: | |
| 221 | 新增: //// 转移数据 | |
| 222 | 新增: ExecuteNonQuery($"INSERT INTO {tempName}({field}) SELECT {field} FROM {tableName}"); | |
| 223 | 新增: | |
| 224 | 新增: | |
| 225 | 新增: // 删除旧表 | |
| 226 | 新增: ExecuteNonQuery($"drop table {tableName}"); | |
| 227 | 新增: | |
| 228 | 新增: | |
| 229 | 新增: // 重新命名临时表 | |
| 230 | 新增: ExecuteNonQuery($"alter table {tempName} rename to {tableName}"); | |
| 121 | 231 | } |
| 122 | 232 | } |
| 123 | 233 | |
| 124 | 234 | } |
| 235 | 新增: return true; | |
| 236 | 新增: } | |
| 237 | 新增: catch (Exception ex) | |
| 238 | 新增: { | |
| 239 | 新增: Logger.Error($"SQLiteBuilder handle fail!Exception Message:{ex.Message}"); | |
| 240 | 新增: return false; | |
| 241 | 新增: } | |
| 242 | 新增: } | |
| 243 | 新增: | |
| 244 | 新增: | |
| 245 | 新增: /// <summary> | |
| 246 | 新增: /// 数据迁移,1.0.0.2升级1.0.0.3时需要转移表数据 | |
| 247 | 新增: /// </summary> | |
| 248 | 新增: private void HandleVersion1002Migrate() | |
| 249 | 新增: { | |
| 250 | 新增: //if (ExecuteNonQuery("select count(*) from sqlite_master where type='table' and name='AppModels'") != 0) | |
| 251 | 新增: //{ | |
| 252 | 新增: // return; | |
| 253 | 新增: //} | |
| 254 | 新增: ExecuteNonQuery($"insert into AppModels(ID,Name,Description,File,TotalTime) select null,ProcessName as Name,ProcessDescription as Description,File,sum(Time) as TotalTime from DailyLogModels where 1=1 GROUP BY Name"); | |
| 255 | 新增: | |
| 256 | 新增: using (var con = new SQLiteConnection(connstr)) | |
| 257 | 新增: { | |
| 258 | 新增: con.Open(); | |
| 259 | 新增: using (var cmd = new SQLiteCommand(con)) | |
| 260 | 新增: { | |
| 261 | 新增: cmd.CommandText = $"select ID,Name,Description from AppModels GROUP BY Name"; | |
| 262 | 新增: | |
| 263 | 新增: List<string> sqlList = new List<string>(); | |
| 264 | 新增: | |
| 265 | 新增: using (var rd = cmd.ExecuteReader()) | |
| 266 | 新增: { | |
| 267 | 新增: while (rd.Read()) | |
| 268 | 新增: { | |
| 269 | 新增: var ID = rd[0]; | |
| 270 | 新增: var Name = rd[1].ToString(); | |
| 271 | 新增: var Description = rd[2].ToString(); | |
| 272 | 新增: | |
| 273 | 新增: var icon = Iconer.Get(Name, Description); | |
| 274 | 新增: | |
| 275 | 新增: sqlList.Add($"update DailyLogModels set AppModelID={ID} where ProcessName='{Name}'"); | |
| 276 | 新增: sqlList.Add($"update HoursLogModels set AppModelID={ID} where ProcessName='{Name}'"); | |
| 277 | 新增: | |
| 278 | 新增: | |
| 279 | 新增: sqlList.Add($"update AppModels set IconFile='{icon}' where ID={ID}"); | |
| 280 | 新增: } | |
| 281 | 新增: } | |
| 125 | 282 | |
| 283 | 新增: cmd.CommandText = string.Join("; ", sqlList.ToArray()); | |
| 284 | 新增: cmd.ExecuteNonQuery(); | |
| 285 | 新增: } | |
| 126 | 286 | } |
| 287 | 新增: | |
| 127 | 288 | } |
| 128 | 289 | |
| 129 | 290 | #region 是否需要处理 |
| 291 | 新增: /// <summary> | |
| 292 | 新增: /// 判断是否需要处理数据,比对core程序集版本号 | |
| 293 | 新增: /// </summary> | |
| 294 | 新增: /// <returns></returns> | |
| 130 | 295 | private bool IsHandleDb() |
| 131 | 296 | { |
| 132 | 297 | string dir = Path.GetDirectoryName(versionFile); |
| @@ -136,22 +301,24 @@ namespace Core.Librarys.SQLite | ||
| 136 | 301 | } |
| 137 | 302 | |
| 138 | 303 | bool f = File.Exists(versionFile); |
| 139 | 删除: string appVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |
| 304 | 新增: | |
| 305 | 新增: // core程序集版本号 | |
| 306 | 新增: string coreVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |
| 140 | 307 | if (f) |
| 141 | 308 | { |
| 142 | 309 | //存在版本文件对比是否需要更新 |
| 143 | 310 | string dbVersion = File.ReadAllText(versionFile); |
| 144 | 删除: if (dbVersion != appVersion) | |
| 311 | 新增: if (dbVersion != coreVersion) | |
| 145 | 312 | { |
| 146 | 313 | //版本不一致需要更新 |
| 147 | 删除: File.WriteAllText(versionFile, appVersion); | |
| 314 | 新增: File.WriteAllText(versionFile, coreVersion); | |
| 148 | 315 | return true; |
| 149 | 316 | } |
| 150 | 317 | //不需要更新 |
| 151 | 318 | return false; |
| 152 | 319 | } |
| 153 | 320 | |
| 154 | 删除: File.WriteAllText(versionFile, appVersion); | |
| 321 | 新增: File.WriteAllText(versionFile, coreVersion); | |
| 155 | 322 | return true; |
| 156 | 323 | } |
| 157 | 324 | |
| @@ -166,7 +333,12 @@ namespace Core.Librarys.SQLite | ||
| 166 | 333 | /// <returns></returns> |
| 167 | 334 | private string GetCreateColumnSQL(string tableName, IModelProperties properties) |
| 168 | 335 | { |
| 169 | 删除: string typeDefault = properties.NotNull ? properties.Type == "int" ? "NOT NULL DEFAULT 0" : "NOT NULL DEFAULT ''" : ""; | |
| 336 | 新增: string typeDefault = !properties.PK ? properties.Type == DbType.@int ? "NULL DEFAULT 0" : "NULL DEFAULT ''" : ""; | |
| 337 | 新增: | |
| 338 | 新增: if (properties.PK) | |
| 339 | 新增: { | |
| 340 | 新增: properties.Type = DbType.INTEGER; | |
| 341 | 新增: } | |
| 170 | 342 | return $"ALTER table {tableName} ADD COLUMN [{properties.Name}] {properties.Type} {typeDefault}"; |
| 171 | 343 | } |
| 172 | 344 | #endregion |
| @@ -177,14 +349,23 @@ namespace Core.Librarys.SQLite | ||
| 177 | 349 | /// </summary> |
| 178 | 350 | /// <param name="model">模型信息</param> |
| 179 | 351 | /// <returns></returns> |
| 180 | 删除: private string GetCreateTableSQL(IModelInfo model) | |
| 352 | 新增: private string GetCreateTableSQL(IModelInfo model, string tableName = null) | |
| 181 | 353 | { |
| 182 | 删除: string sql = $"CREATE TABLE \"{model.TableName}\" ("; | |
| 354 | 新增: tableName = string.IsNullOrEmpty(tableName) ? model.TableName : tableName; | |
| 355 | 新增: | |
| 356 | 新增: string sql = $"CREATE TABLE \"{tableName}\" ("; | |
| 183 | 357 | foreach (var p in model.Properties) |
| 184 | 358 | { |
| 185 | 删除: string add = p.PK ? $"{p.Type} PRIMARY KEY" : p.Type + (p.NotNull ? " NOT NULL" : ""); | |
| 359 | 新增: string typeDefault = p.Type == DbType.@int ? " NULL DEFAULT 0" : " NULL DEFAULT ''"; | |
| 360 | 新增: if (p.PK) | |
| 361 | 新增: { | |
| 362 | 新增: typeDefault = ""; | |
| 363 | 新增: p.Type = DbType.INTEGER; | |
| 364 | 新增: } | |
| 365 | 新增: | |
| 366 | 新增: string add = p.PK ? $"{p.Type} PRIMARY KEY" : p.Type.ToString(); | |
| 186 | 367 | string addChar = p == model.Properties[0] ? "" : ","; |
| 187 | 删除: sql += $"{addChar}[{p.Name}] {add}"; | |
| 368 | 新增: sql += $"{addChar}[{p.Name}] {add}{typeDefault}"; | |
| 188 | 369 | } |
| 189 | 370 | sql += ")"; |
| 190 | 371 | return sql; |
| @@ -238,11 +419,13 @@ namespace Core.Librarys.SQLite | ||
| 238 | 419 | //属性获取 |
| 239 | 420 | foreach (var p in model.Properties) |
| 240 | 421 | { |
| 422 | 新增: Enum.TryParse(p.TypeName, out DbType dbType); | |
| 423 | 新增: | |
| 241 | 424 | ps.Add(new IModelProperties() |
| 242 | 425 | { |
| 243 | 426 | Name = p.Name, |
| 244 | 427 | PK = p.IsStoreGeneratedIdentity, |
| 245 | 删除: Type = p.TypeName == "int" && p.IsStoreGeneratedIdentity ? "INTEGER" : p.TypeName | |
| 428 | 新增: Type = dbType | |
| 246 | 429 | }); |
| 247 | 430 | } |
| 248 | 431 | result.Add(i); |
| @@ -303,7 +486,8 @@ namespace Core.Librarys.SQLite | ||
| 303 | 486 | { |
| 304 | 487 | var mp = new IModelProperties(); |
| 305 | 488 | mp.Name = rd["name"].ToString(); |
| 306 | 删除: mp.Type = rd["type"].ToString(); | |
| 489 | 新增: Enum.TryParse(rd["type"].ToString(), out DbType dbType); | |
| 490 | 新增: mp.Type = dbType; | |
| 307 | 491 | mp.PK = rd["pk"].ToString() == "1"; |
| 308 | 492 | result.Add(mp); |
| 309 | 493 | } |
| @@ -334,6 +518,8 @@ namespace Core.Librarys.SQLite | ||
| 334 | 518 | |
| 335 | 519 | } |
| 336 | 520 | } |
| 521 | 新增: | |
| 522 | 新增: | |
| 337 | 523 | } |
| 338 | 524 | |
| 339 | 525 | } |
| 文件末尾没有换行 | ||
| @@ -19,6 +19,7 @@ namespace Core.Librarys.SQLite | ||
| 19 | 19 | /// 时段数据 |
| 20 | 20 | /// </summary> |
| 21 | 21 | public DbSet<HoursLogModel> HoursLog { get; set; } |
| 22 | 新增: public DbSet<AppModel> App { get; set; } | |
| 22 | 23 | |
| 23 | 24 | // public StatisticContext(string n) |
| 24 | 25 | //: base("StatisticContext") |
| @@ -37,7 +38,7 @@ namespace Core.Librarys.SQLite | ||
| 37 | 38 | protected override void OnModelCreating(DbModelBuilder modelBuilder) |
| 38 | 39 | { |
| 39 | 40 | var model = modelBuilder.Build(Database.Connection); |
| 40 | 删除: new SQLiteBuilder(model).Handle(); | |
| 41 | 新增: new SQLiteBuilder(model).SelfCheck(); | |
| 41 | 42 | } |
| 42 | 43 | } |
| 43 | 44 | } |
| 文件末尾没有换行 | ||
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | using Core.Enums; |
| 2 | 2 | using Core.Librarys; |
| 3 | 3 | using Core.Librarys.SQLite; |
| 4 | 新增:using Core.Models; | |
| 4 | 5 | using Core.Models.Config; |
| 5 | 6 | using Core.Models.Config.Link; |
| 6 | 7 | using Core.Servicers.Interfaces; |
| @@ -118,24 +119,40 @@ namespace Core.Servicers.Instances | ||
| 118 | 119 | |
| 119 | 120 | public void Run() |
| 120 | 121 | { |
| 121 | 删除: // 加载应用配置(确保配置文件最先加载 | |
| 122 | 删除: appConfig.Load(); | |
| 123 | 删除: config = appConfig.GetConfig(); | |
| 122 | 新增: Task.Run(() => | |
| 123 | 新增: { | |
| 124 | 新增: Debug.WriteLine("start"); | |
| 125 | 新增: // 数据库自检 | |
| 126 | 新增: using (var db = new StatisticContext()) | |
| 127 | 新增: { | |
| 128 | 新增: db.Database.ExecuteSqlCommand("select count(*) from sqlite_master where type='table' and name='tai'"); | |
| 129 | 新增: } | |
| 130 | 新增: // 加载app信息 | |
| 131 | 新增: data.LoadAppList(); | |
| 132 | 新增: | |
| 133 | 新增: // 加载应用配置(确保配置文件最先加载 | |
| 134 | 新增: appConfig.Load(); | |
| 135 | 新增: config = appConfig.GetConfig(); | |
| 124 | 136 | |
| 125 | 删除: // 日期变化观察 | |
| 126 | 删除: dateObserver.Start(); | |
| 137 | 新增: // 日期变化观察 | |
| 138 | 新增: dateObserver.Start(); | |
| 127 | 139 | |
| 128 | 删除: // 启动进程观察 | |
| 129 | 删除: observer.Start(); | |
| 140 | 新增: // 启动进程观察 | |
| 141 | 新增: observer.Start(); | |
| 130 | 142 | |
| 131 | 删除: // 启动睡眠监测 | |
| 132 | 删除: sleepdiscover.Start(); | |
| 143 | 新增: // 启动睡眠监测 | |
| 144 | 新增: sleepdiscover.Start(); | |
| 145 | 新增: Debug.WriteLine("over!"); | |
| 146 | 新增: | |
| 147 | 新增: }); | |
| 133 | 148 | |
| 134 | 149 | } |
| 135 | 150 | |
| 136 | 151 | public void Exit() |
| 137 | 152 | { |
| 138 | 153 | observer?.Stop(); |
| 154 | 新增: | |
| 155 | 新增: data.SaveAppChanges(); | |
| 139 | 156 | } |
| 140 | 157 | |
| 141 | 158 | |
| @@ -153,6 +170,9 @@ namespace Core.Servicers.Instances | ||
| 153 | 170 | activeProcess = null; |
| 154 | 171 | //activeSeconds = 0; |
| 155 | 172 | //activeTimer.Stop(); |
| 173 | 新增: | |
| 174 | 新增: // 更新app数据 | |
| 175 | 新增: data.SaveAppChanges(); | |
| 156 | 176 | } |
| 157 | 177 | else if (sleepStatus == SleepStatus.Wake) |
| 158 | 178 | { |
| @@ -161,8 +181,46 @@ namespace Core.Servicers.Instances | ||
| 161 | 181 | } |
| 162 | 182 | } |
| 163 | 183 | |
| 184 | 新增: | |
| 185 | 新增: /// <summary> | |
| 186 | 新增: /// 检查焦点app是否已经在库 | |
| 187 | 新增: /// </summary> | |
| 188 | 新增: /// <param name="processName"></param> | |
| 189 | 新增: /// <param name="description"></param> | |
| 190 | 新增: /// <param name="file"></param> | |
| 191 | 新增: private void CheckApp(string processName, string description, string file) | |
| 192 | 新增: { | |
| 193 | 新增: if (string.IsNullOrEmpty(file) || string.IsNullOrEmpty(processName)) | |
| 194 | 新增: { | |
| 195 | 新增: return; | |
| 196 | 新增: } | |
| 197 | 新增: | |
| 198 | 新增: | |
| 199 | 新增: if (!config.Behavior.IgnoreProcessList.Contains(processName) | |
| 200 | 新增: && !IgnoreProcess.Contains(processName)) | |
| 201 | 新增: { | |
| 202 | 新增: AppModel app = data.GetApp(processName); | |
| 203 | 新增: if (app == null) | |
| 204 | 新增: { | |
| 205 | 新增: // 提取icon | |
| 206 | 新增: string iconFile = Iconer.ExtractFromFile(file, processName, description); | |
| 207 | 新增: | |
| 208 | 新增: data.AddApp(new AppModel() | |
| 209 | 新增: { | |
| 210 | 新增: Name = processName, | |
| 211 | 新增: Description = description, | |
| 212 | 新增: File = file, | |
| 213 | 新增: CategoryID = 0, | |
| 214 | 新增: IconFile = iconFile, | |
| 215 | 新增: }); | |
| 216 | 新增: } | |
| 217 | 新增: } | |
| 218 | 新增: } | |
| 219 | 新增: | |
| 164 | 220 | private void Observer_OnAppActive(string processName, string description, string file) |
| 165 | 221 | { |
| 222 | 新增: CheckApp(processName, description, file); | |
| 223 | 新增: | |
| 166 | 224 | if (activeProcess != processName && activeProcessFile != file) |
| 167 | 225 | { |
| 168 | 226 | UpdateTime(); |
| @@ -185,8 +243,7 @@ namespace Core.Servicers.Instances | ||
| 185 | 243 | // activeTimer.Start(); |
| 186 | 244 | //} |
| 187 | 245 | |
| 188 | 删除: // 提取icon | |
| 189 | 删除: Iconer.ExtractFromFile(file, processName, description); | |
| 246 | 新增: | |
| 190 | 247 | } |
| 191 | 248 | else |
| 192 | 249 | { |
| @@ -266,7 +323,7 @@ namespace Core.Servicers.Instances | ||
| 266 | 323 | |
| 267 | 324 | |
| 268 | 325 | |
| 269 | 删除: Logger.Info("【"+sleepStatus + "】进程:" + activeProcess + " 更新时间:" + seconds + ",开始时间:" + activeStartTime.ToString() + ",当前时间:" + DateTime.Now.ToString()); | |
| 326 | 新增: Logger.Info("【" + sleepStatus + "】进程:" + activeProcess + " 更新时间:" + seconds + ",开始时间:" + activeStartTime.ToString() + ",当前时间:" + DateTime.Now.ToString()); | |
| 270 | 327 | |
| 271 | 328 | |
| 272 | 329 | data.Set(activeProcess, activeProcessDescription, activeProcessFile, seconds); |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | using Core.Librarys; |
| 2 | 新增:using Core.Librarys.SQLite; | |
| 2 | 3 | using Core.Servicers.Instances; |
| 3 | 4 | using Core.Servicers.Interfaces; |
| 4 | 5 | using Microsoft.Extensions.DependencyInjection; |
| @@ -40,6 +41,10 @@ namespace UI | ||
| 40 | 41 | private DefaultWindow mainWindow; |
| 41 | 42 | public App() |
| 42 | 43 | { |
| 44 | 新增: InitStatusBarIcon(); | |
| 45 | 新增: | |
| 46 | 新增: WatchStatus(); | |
| 47 | 新增: | |
| 43 | 48 | DispatcherUnhandledException += App_DispatcherUnhandledException; |
| 44 | 49 | |
| 45 | 50 | var serviceCollection = new ServiceCollection(); |
| @@ -50,6 +55,13 @@ namespace UI | ||
| 50 | 55 | protected override void OnExit(ExitEventArgs e) |
| 51 | 56 | { |
| 52 | 57 | base.OnExit(e); |
| 58 | 新增: | |
| 59 | 新增: var data = serviceProvider.GetService<IData>(); | |
| 60 | 新增: | |
| 61 | 新增: data.SaveAppChanges(); | |
| 62 | 新增: | |
| 63 | 新增: Logger.Save(true); | |
| 64 | 新增: | |
| 53 | 65 | statusBarIcon.Visible = false; |
| 54 | 66 | } |
| 55 | 67 | private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) |
| @@ -57,6 +69,8 @@ namespace UI | ||
| 57 | 69 | // 记录崩溃错误 |
| 58 | 70 | Logger.Error("[程序崩溃异常] " + e.Exception.Message); |
| 59 | 71 | |
| 72 | 新增: Logger.Save(true); | |
| 73 | 新增: | |
| 60 | 74 | e.Handled = true; |
| 61 | 75 | |
| 62 | 76 | Shutdown(); |
| @@ -95,8 +109,8 @@ namespace UI | ||
| 95 | 109 | CreateStatusBarIconMenu(); |
| 96 | 110 | |
| 97 | 111 | statusBarIcon = new System.Windows.Forms.NotifyIcon(); |
| 98 | 删除: statusBarIcon.Text = "Tai!"; | |
| 99 | 删除: Stream iconStream = GetResourceStream(new Uri("pack://application:,,,/Tai;component/Resources/Icons/tai32.ico")).Stream; | |
| 112 | 新增: statusBarIcon.Text = "Tai! [数据库自检中...请稍后]"; | |
| 113 | 新增: Stream iconStream = GetResourceStream(new Uri("pack://application:,,,/Tai;component/Resources/Icons/taibusy.ico")).Stream; | |
| 100 | 114 | statusBarIcon.Icon = new Icon(iconStream); |
| 101 | 115 | //statusBarIcon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(System.Reflection.Assembly.GetEntryAssembly().ManifestModule.Name); |
| 102 | 116 | |
| @@ -106,7 +120,7 @@ namespace UI | ||
| 106 | 120 | } |
| 107 | 121 | private void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) |
| 108 | 122 | { |
| 109 | 删除: if (e.Button == System.Windows.Forms.MouseButtons.Right) | |
| 123 | 新增: if (e.Button == System.Windows.Forms.MouseButtons.Right && !SQLiteBuilder.IsSelfChecking) | |
| 110 | 124 | { |
| 111 | 125 | //右键单击弹出托盘菜单 |
| 112 | 126 | contextMenu.IsOpen = true; |
| @@ -114,7 +128,7 @@ namespace UI | ||
| 114 | 128 | } |
| 115 | 129 | private void NotifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e) |
| 116 | 130 | { |
| 117 | 删除: if (e.Button == System.Windows.Forms.MouseButtons.Left) | |
| 131 | 新增: if (e.Button == System.Windows.Forms.MouseButtons.Left && !SQLiteBuilder.IsSelfChecking) | |
| 118 | 132 | { |
| 119 | 133 | //双击托盘图标显示主窗口 |
| 120 | 134 | ShowMainWindow(); |
| @@ -205,7 +219,6 @@ namespace UI | ||
| 205 | 219 | // 创建保活窗口 |
| 206 | 220 | keepaliveWindow = new HideWindow(); |
| 207 | 221 | |
| 208 | 删除: InitStatusBarIcon(); | |
| 209 | 222 | } |
| 210 | 223 | |
| 211 | 224 | private void ShowMainWindow() |
| @@ -227,5 +240,18 @@ namespace UI | ||
| 227 | 240 | mainWindow.Show(); |
| 228 | 241 | mainWindow.Activate(); |
| 229 | 242 | } |
| 243 | 新增: | |
| 244 | 新增: private async void WatchStatus() | |
| 245 | 新增: { | |
| 246 | 新增: await Task.Run(() => | |
| 247 | 新增: { | |
| 248 | 新增: while (SQLiteBuilder.IsSelfChecking) | |
| 249 | 新增: { | |
| 250 | 新增: } | |
| 251 | 新增: statusBarIcon.Text = "Tai!"; | |
| 252 | 新增: Stream iconStream = GetResourceStream(new Uri("pack://application:,,,/Tai;component/Resources/Icons/tai32.ico")).Stream; | |
| 253 | 新增: statusBarIcon.Icon = new Icon(iconStream); | |
| 254 | 新增: }); | |
| 255 | 新增: } | |
| 230 | 256 | } |
| 231 | 257 | } |

