WechatDBHelper.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Security.Cryptography;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using WechatPCMsgBakTool.Model;
  9. namespace WechatPCMsgBakTool.Helpers
  10. {
  11. public class WechatDBHelper
  12. {
  13. private static string ResPath = "";
  14. private static string CurrentPath = AppDomain.CurrentDomain.BaseDirectory;
  15. private static string UserWorkPath = "";
  16. private static int MaxMediaDBCount = 0;
  17. private static int MaxMsgDBCount = 0;
  18. public static DBInfo GetDBInfo()
  19. {
  20. return new DBInfo() { MaxMediaDBCount = MaxMediaDBCount, MaxMsgDBCount = MaxMsgDBCount, UserPath = UserWorkPath, ResPath = ResPath };
  21. }
  22. public static DBInfo GetDBinfoOnLocal(string path)
  23. {
  24. string md5 = GetMd5Hash(path);
  25. string tmpPath = Path.Combine(CurrentPath, md5);
  26. string decPath = Path.Combine(tmpPath, "DecDB");
  27. string[] files = Directory.GetFiles(decPath);
  28. int media = 0;
  29. int msg = 0;
  30. foreach(string file in files)
  31. {
  32. FileInfo fileInfo = new FileInfo(file);
  33. if(fileInfo.Extension == ".db")
  34. {
  35. string name = fileInfo.Name.Replace(".db", "");
  36. if(name.Substring(0,3) == "MSG")
  37. {
  38. name = name.Replace("MSG", "");
  39. int currentDB = int.Parse(name);
  40. if(currentDB > msg)
  41. msg = currentDB;
  42. continue;
  43. }
  44. if(name.Substring(0,8)== "MediaMSG")
  45. {
  46. name = name.Replace("MediaMSG", "");
  47. int currentDB = int.Parse(name);
  48. if (currentDB > media)
  49. media = currentDB;
  50. continue;
  51. }
  52. }
  53. }
  54. return new DBInfo() { MaxMediaDBCount = media, MaxMsgDBCount = msg, UserPath = tmpPath, ResPath = path };
  55. }
  56. public static void CreateUserWorkPath(string path)
  57. {
  58. ResPath = path;
  59. string md5 = GetMd5Hash(path);
  60. string tmpPath = Path.Combine(CurrentPath, md5);
  61. if (!Directory.Exists(tmpPath))
  62. {
  63. Directory.CreateDirectory(tmpPath);
  64. }
  65. UserWorkPath = tmpPath;
  66. }
  67. public static string MoveUserData(string path)
  68. {
  69. if(UserWorkPath != "")
  70. {
  71. //创建db库
  72. string db = Path.Combine(UserWorkPath, "DB");
  73. if (!Directory.Exists(db))
  74. {
  75. Directory.CreateDirectory(db);
  76. }
  77. //核心数据库查找
  78. List<string> dbPathArray = new List<string>();
  79. string userDBPath = Path.Combine(path, "Msg");
  80. if (!Directory.Exists(userDBPath))
  81. return "用户目录不存在,创建失败";
  82. string mainDB = Path.Combine(userDBPath, "MicroMsg.db");
  83. if (!File.Exists(mainDB))
  84. return "微信主数据库不存在,创建失败";
  85. else
  86. dbPathArray.Add(mainDB);
  87. string actDB = Path.Combine(userDBPath, "MultiSearchChatMsg.db");
  88. if(!File.Exists(actDB))
  89. return "微信附件数据库不存在,创建失败";
  90. else
  91. dbPathArray.Add(actDB);
  92. string dbmsg = Path.Combine(userDBPath, "Multi");
  93. bool mediaDBExists = false;
  94. bool msgDBExists = false;
  95. for(int i = 0; i < 100; i++)
  96. {
  97. string mediaDBPath = Path.Combine(dbmsg, string.Format("MediaMSG{0}.db", i.ToString()));
  98. string msgDBPath = Path.Combine(dbmsg, string.Format("MSG{0}.db", i.ToString()));
  99. mediaDBExists = File.Exists(mediaDBPath);
  100. msgDBExists = File.Exists(msgDBPath);
  101. if (i == 0 && !mediaDBExists && !msgDBExists)
  102. {
  103. return "微信聊天记录数据不存在,创建失败";
  104. }
  105. if(mediaDBExists)
  106. dbPathArray.Add(mediaDBPath);
  107. if (msgDBExists)
  108. dbPathArray.Add(msgDBPath);
  109. if (!msgDBExists && !msgDBExists)
  110. break;
  111. }
  112. foreach(string dbPath in dbPathArray) {
  113. FileInfo file = new FileInfo(dbPath);
  114. string to = Path.Combine(db, file.Name);
  115. if(!File.Exists(to))
  116. File.Copy(dbPath, to);
  117. }
  118. return "";
  119. }
  120. return "请复制目录至文本框内";
  121. }
  122. public static void DecryUserData(byte[] key)
  123. {
  124. string dbPath = Path.Combine(UserWorkPath, "DB");
  125. string decPath = Path.Combine(UserWorkPath, "DecDB");
  126. if(!Directory.Exists(decPath))
  127. Directory.CreateDirectory(decPath);
  128. string[] filePath = Directory.GetFiles(dbPath);
  129. foreach (string file in filePath)
  130. {
  131. FileInfo info = new FileInfo(file);
  132. var db_bytes = File.ReadAllBytes(file);
  133. var decrypted_file_bytes = DecryptionHelper.DecryptDB(db_bytes, key);
  134. if (decrypted_file_bytes == null || decrypted_file_bytes.Length == 0)
  135. {
  136. Console.WriteLine("解密后的数组为空");
  137. }
  138. else
  139. {
  140. File.WriteAllBytes(Path.Combine(decPath, info.Name), decrypted_file_bytes);
  141. }
  142. }
  143. }
  144. private static string GetMd5Hash(string input)
  145. {
  146. using (MD5 md5Hash = MD5.Create())
  147. {
  148. // Convert the input string to a byte array and compute the hash.
  149. byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
  150. // Create a new Stringbuilder to collect the bytes
  151. // and create a string.
  152. StringBuilder sBuilder = new StringBuilder();
  153. // Loop through each byte of the hashed data
  154. // and format each one as a hexadecimal string.
  155. for (int i = 0; i < data.Length; i++)
  156. {
  157. sBuilder.Append(data[i].ToString("x2"));
  158. }
  159. // Return the hexadecimal string.
  160. return sBuilder.ToString();
  161. }
  162. }
  163. }
  164. }