2
0

Main.xaml.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using K4os.Compression.LZ4;
  2. using K4os.Compression.LZ4.Encoders;
  3. using K4os.Compression.LZ4.Streams;
  4. using Newtonsoft.Json;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Diagnostics;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Reflection.PortableExecutable;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15. using System.Windows;
  16. using System.Windows.Controls;
  17. using System.Windows.Data;
  18. using System.Windows.Documents;
  19. using System.Windows.Input;
  20. using System.Windows.Media;
  21. using System.Windows.Media.Imaging;
  22. using System.Xml;
  23. using WechatPCMsgBakTool.Helpers;
  24. using WechatPCMsgBakTool.Interface;
  25. using WechatPCMsgBakTool.Model;
  26. namespace WechatPCMsgBakTool
  27. {
  28. /// <summary>
  29. /// Main.xaml 的交互逻辑
  30. /// </summary>
  31. public partial class Main : Window
  32. {
  33. private UserBakConfig? CurrentUserBakConfig = null;
  34. private WXUserReader? UserReader = null;
  35. private ObservableCollection<UserBakConfig> userBakConfigs = new ObservableCollection<UserBakConfig>();
  36. public Main()
  37. {
  38. Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
  39. InitializeComponent();
  40. LoadWorkspace();
  41. this.Title += $" {Application.ResourceAssembly.GetName().Version}";
  42. }
  43. private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
  44. {
  45. MessageBox.Show("发生了未知错误,记录已写入到根目录err.log,如果可以,欢迎反馈给开发人员,非常感谢", "错误");
  46. File.AppendAllText("err.log", "\r\n\r\n\r\n=============================\r\n");
  47. File.AppendAllText("err.log", string.Format("异常时间:{0}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
  48. File.AppendAllText("err.log", e.Exception.ToString());
  49. return;
  50. }
  51. private void LoadWorkspace()
  52. {
  53. userBakConfigs.Clear();
  54. string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "workspace");
  55. if (Directory.Exists(path))
  56. {
  57. string[] files = Directory.GetFiles(path);
  58. foreach(string file in files)
  59. {
  60. string type = file.Substring(file.Length - 5, 5);
  61. if(type == ".json")
  62. {
  63. string jsonString = File.ReadAllText(file);
  64. UserBakConfig? userBakConfig = null;
  65. try
  66. {
  67. userBakConfig = JsonConvert.DeserializeObject<UserBakConfig>(jsonString);
  68. }
  69. catch
  70. {
  71. MessageBox.Show("读取到异常工作区文件,请确认备份数据是否正常\r\n文件路径:" + file,"错误");
  72. }
  73. if(userBakConfig != null)
  74. {
  75. userBakConfigs.Add(userBakConfig);
  76. }
  77. }
  78. }
  79. }
  80. list_workspace.ItemsSource = userBakConfigs;
  81. }
  82. private void btn_decrypt_Click(object sender, RoutedEventArgs e)
  83. {
  84. if(CurrentUserBakConfig != null)
  85. {
  86. if (!CurrentUserBakConfig.Decrypt)
  87. {
  88. bool? mem_find_key = rb_find_mem.IsChecked;
  89. if(mem_find_key == null)
  90. {
  91. MessageBox.Show("请选择key获取方式");
  92. return;
  93. }
  94. byte[]? key = null;
  95. try
  96. {
  97. key = DecryptionHelper.GetWechatKey((bool)mem_find_key,CurrentUserBakConfig.Account);
  98. if (key == null)
  99. MessageBox.Show("获取到的秘钥为空");
  100. File.AppendAllText("debug.log", BitConverter.ToString(key, 0));
  101. }
  102. catch (Exception ex)
  103. {
  104. if(ex.Source == "Newtonsoft.Json")
  105. {
  106. MessageBox.Show("版本文件读取失败,请检查版本文件内容是否为正确的json格式", "错误");
  107. }
  108. else
  109. {
  110. MessageBox.Show(ex.Message);
  111. }
  112. return;
  113. }
  114. //byte[]? key = DecryptionHelper.GetWechatKey();
  115. if (key == null)
  116. {
  117. MessageBox.Show("微信密钥获取失败,请检查微信是否打开,或者版本不兼容");
  118. return;
  119. }
  120. string key_string = BitConverter.ToString(key, 0).Replace("-", string.Empty).ToLower().ToUpper();
  121. string source = Path.Combine(CurrentUserBakConfig.UserWorkspacePath, "OriginalDB");
  122. string to = Path.Combine(CurrentUserBakConfig.UserWorkspacePath, "DecDB");
  123. try
  124. {
  125. WechatDBHelper.DecryUserData(key, source, to);
  126. MessageBox.Show("解密完成,请点击读取数据");
  127. CurrentUserBakConfig.Decrypt = true;
  128. WXWorkspace.SaveConfig(CurrentUserBakConfig);
  129. LoadWorkspace();
  130. }
  131. catch (Exception ex)
  132. {
  133. MessageBox.Show("解密过程出现错误:" + ex.Message);
  134. }
  135. }
  136. }
  137. }
  138. private void btn_read_Click(object sender, RoutedEventArgs e)
  139. {
  140. if(CurrentUserBakConfig == null)
  141. {
  142. MessageBox.Show("请先选择工作区");
  143. return;
  144. }
  145. UserReader = new WXUserReader(CurrentUserBakConfig);
  146. list_sessions.ItemsSource = UserReader.GetWXContacts();
  147. }
  148. private void list_workspace_SelectionChanged(object sender, SelectionChangedEventArgs e)
  149. {
  150. CurrentUserBakConfig = list_workspace.SelectedItem as UserBakConfig;
  151. if(CurrentUserBakConfig != null)
  152. {
  153. user_path.Content = "用户路径:" + CurrentUserBakConfig.UserResPath;
  154. if (CurrentUserBakConfig.Decrypt)
  155. {
  156. btn_decrypt.IsEnabled = false;
  157. btn_read.IsEnabled = true;
  158. }
  159. else
  160. {
  161. btn_decrypt.IsEnabled = true;
  162. btn_read.IsEnabled = false;
  163. }
  164. }
  165. }
  166. private void list_sessions_MouseDoubleClick(object sender, MouseButtonEventArgs e)
  167. {
  168. }
  169. private void Button_Click(object sender, RoutedEventArgs e)
  170. {
  171. WXContact? wXContact = list_sessions.SelectedItem as WXContact;
  172. if(UserReader == null)
  173. {
  174. MessageBox.Show("请先点击读取已解密工作区");
  175. return;
  176. }
  177. if(wXContact == null || CurrentUserBakConfig == null)
  178. {
  179. MessageBox.Show("请先选择要导出的联系人");
  180. return;
  181. }
  182. IExport export = new HtmlExport();
  183. export.InitTemplate(wXContact);
  184. export.SetMsg(UserReader, wXContact);
  185. export.SetEnd();
  186. //string path = UserReader.GetSavePath(wXContact);
  187. string path = Path.Combine(CurrentUserBakConfig.UserWorkspacePath, wXContact.UserName + ".html");
  188. export.Save(path);
  189. MessageBox.Show("导出完成");
  190. }
  191. private void Button_Click_1(object sender, RoutedEventArgs e)
  192. {
  193. SelectWechat selectWechat = new SelectWechat();
  194. selectWechat.ShowDialog();
  195. if(selectWechat.SelectProcess != null)
  196. {
  197. string path = selectWechat.SelectProcess.DBPath.Replace("\\Msg\\MicroMsg.db", "");
  198. try
  199. {
  200. WXWorkspace wXWorkspace = new WXWorkspace(path, selectWechat.SelectProcess.Account);
  201. wXWorkspace.MoveDB();
  202. MessageBox.Show("创建工作区成功");
  203. LoadWorkspace();
  204. }
  205. catch (Exception)
  206. {
  207. MessageBox.Show("创建工作区失败,请检查路径是否正确");
  208. }
  209. }
  210. }
  211. private void btn_search_Click(object sender, RoutedEventArgs e)
  212. {
  213. if(UserReader == null)
  214. {
  215. MessageBox.Show("请先读取工作区数据");
  216. return;
  217. }
  218. if(cb_del_search.IsChecked != null)
  219. {
  220. if (!(bool)cb_del_search.IsChecked)
  221. list_sessions.ItemsSource = UserReader.GetWXContacts(find_user.Text);
  222. else
  223. {
  224. List<WXMsg>? wXMsgs = UserReader.GetWXMsgs(find_user.Text);
  225. if(wXMsgs != null)
  226. {
  227. if(wXMsgs.Count > 0)
  228. {
  229. List<WXContact> wXContacts = new List<WXContact>() { new WXContact() { NickName = wXMsgs[0].StrTalker, UserName = wXMsgs[0].StrTalker } };
  230. list_sessions.ItemsSource = wXContacts;
  231. }
  232. }
  233. }
  234. }
  235. }
  236. private void btn_analyse_Click(object sender, RoutedEventArgs e)
  237. {
  238. if(UserReader == null || CurrentUserBakConfig == null)
  239. {
  240. MessageBox.Show("请先读取数据");
  241. return;
  242. }
  243. Analyse analyse = new Analyse(CurrentUserBakConfig, UserReader);
  244. analyse.Show();
  245. }
  246. private void rb_find_mem_Checked(object sender, RoutedEventArgs e)
  247. {
  248. if(CurrentUserBakConfig!= null)
  249. {
  250. if (string.IsNullOrEmpty(CurrentUserBakConfig.Account))
  251. {
  252. MessageBox.Show("使用该功能需要填写用户名,请务必确认用户名已经正确填写,否则请重建工作区");
  253. return;
  254. }
  255. }
  256. }
  257. private void Button_Click_2(object sender, RoutedEventArgs e)
  258. {
  259. var list = UserReader.GetWXChatRooms();
  260. var users = UserReader.GetWXContacts();
  261. Hashtable hashtable = new Hashtable();
  262. foreach(var u in users)
  263. {
  264. hashtable[u.UserName] = u;
  265. }
  266. foreach(var room in list)
  267. {
  268. if(room.ChatRoomName == "20647511469@chatroom")
  269. {
  270. string[] ids = room.UserNameList.Split("^G");
  271. foreach(string id in ids) {
  272. if (hashtable.ContainsKey(id))
  273. {
  274. WXContact? contact = hashtable[id] as WXContact;
  275. Debug.WriteLine($"{id} 是 ${contact.NickName}");
  276. }
  277. else
  278. {
  279. Debug.WriteLine("不存在");
  280. }
  281. }
  282. }
  283. }
  284. }
  285. }
  286. }