Forráskód Böngészése

v0.9.6.2 Release!
1.初步支持转发消息导出。
2.新增HTML导出全局异常处理,新增LOG方便直接定位

Suxue 1 éve
szülő
commit
932b2d099f
4 módosított fájl, 172 hozzáadás és 132 törlés
  1. 162 87
      Export/HtmlExport.cs
  2. 10 7
      WechatBakTool.csproj
  3. 0 11
      YearReport.xaml
  4. 0 27
      YearReport.xaml.cs

+ 162 - 87
Export/HtmlExport.cs

@@ -11,6 +11,7 @@ using System.Xml;
 using Newtonsoft.Json;
 using WechatBakTool.ViewModel;
 using System.Security.Policy;
+using System.Windows;
 
 namespace WechatBakTool.Export
 {
@@ -60,134 +61,204 @@ namespace WechatBakTool.Export
 
             msgList.Sort((x, y) => x.CreateTime.CompareTo(y.CreateTime));
 
+            bool err = false;
             int msgCount = 0;
             HtmlBody = "";
             StreamWriter streamWriter = new StreamWriter(Path, true);
             foreach (var msg in msgList)
             {
-                HtmlBody += string.Format("<div class=\"msg\"><p class=\"nickname\">{0} <span style=\"padding-left:10px;\">{1}</span></p>", msg.IsSender ? "我" : msg.NickName, TimeStampToDateTime(msg.CreateTime).ToString("yyyy-MM-dd HH:mm:ss"));
-
-                if (msg.Type == 1)
-                    HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", msg.StrContent);
-                else if (msg.Type == 3)
+                try
                 {
-                    string? path = reader.GetAttachment(WXMsgType.Image, msg);
-                    if (path == null)
+                    HtmlBody += string.Format("<div class=\"msg\"><p class=\"nickname\">{0} <span style=\"padding-left:10px;\">{1}</span></p>", msg.IsSender ? "我" : msg.NickName, TimeStampToDateTime(msg.CreateTime).ToString("yyyy-MM-dd HH:mm:ss"));
+
+                    if (msg.Type == 1)
+                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", msg.StrContent);
+                    else if (msg.Type == 3)
                     {
+                        string? path = reader.GetAttachment(WXMsgType.Image, msg);
+                        if (path == null)
+                        {
 #if DEBUG
-                        File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Img Error Path=>", path));
-                        File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),"Img Error Msg=>",JsonConvert.SerializeObject(msg)));
+                            File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Img Error Path=>", path));
+                            File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Img Error Msg=>", JsonConvert.SerializeObject(msg)));
 #endif
-                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "图片转换出现错误或文件不存在");
-                        continue;
+                            HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "图片转换出现错误或文件不存在");
+                            continue;
+                        }
+                        HtmlBody += string.Format("<p class=\"content\"><img src=\"{0}\" style=\"max-height:1000px;max-width:1000px;\"/></p></div>", path);
                     }
-                    HtmlBody += string.Format("<p class=\"content\"><img src=\"{0}\" style=\"max-height:1000px;max-width:1000px;\"/></p></div>", path);
-                }
-                else if (msg.Type == 43)
-                {
-                    string? path = reader.GetAttachment(WXMsgType.Video, msg);
-                    if (path == null)
+                    else if (msg.Type == 43)
                     {
-                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "视频不存在");
-                        continue;
+                        string? path = reader.GetAttachment(WXMsgType.Video, msg);
+                        if (path == null)
+                        {
+                            HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "视频不存在");
+                            continue;
+                        }
+                        HtmlBody += string.Format("<p class=\"content\"><video controls style=\"max-height:300px;max-width:300px;\"><source src=\"{0}\" type=\"video/mp4\" /></video></p></div>", path);
                     }
-                    HtmlBody += string.Format("<p class=\"content\"><video controls style=\"max-height:300px;max-width:300px;\"><source src=\"{0}\" type=\"video/mp4\" /></video></p></div>", path);
-                }
-                else if(msg.Type == 47)
-                {
-                    string? path = reader.GetAttachment(WXMsgType.Emoji, msg);
-                    if (path == null)
+                    else if (msg.Type == 47)
                     {
+                        string? path = reader.GetAttachment(WXMsgType.Emoji, msg);
+                        if (path == null)
+                        {
 #if DEBUG
-                        File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Emoji Error Path=>", path));
-                        File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Emoji Error Msg=>", JsonConvert.SerializeObject(msg)));
+                            File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Emoji Error Path=>", path));
+                            File.AppendAllText("debug.log", string.Format("[D]{0} {1}:{2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Emoji Error Msg=>", JsonConvert.SerializeObject(msg)));
 #endif
-                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "表情未预下载或加密表情");
-                        continue;
-                    }
-                    HtmlBody += string.Format("<p class=\"content\"><img src=\"{0}\" style=\"max-height:300px;max-width:300px;\"/></p></div>", path);
-                }
-                else if (msg.Type == 49)
-                {
-                    if(msg.SubType == 6||msg.SubType == 19||msg.SubType == 40)
-                    {
-                        string? path = reader.GetAttachment(WXMsgType.File, msg);
-                        if(path == null)
-                        {
-                            HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "文件不存在");
+                            HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "表情未预下载或加密表情");
                             continue;
                         }
-                        else
-                        {
-                            HtmlBody += string.Format("<p class=\"content\">{0}</p><p><a href=\"{1}\">点击访问</a></p></div>", "文件:" + path, path);
-                        }
+                        HtmlBody += string.Format("<p class=\"content\"><img src=\"{0}\" style=\"max-height:300px;max-width:300px;\"/></p></div>", path);
                     }
-                    else
+                    else if (msg.Type == 49)
                     {
-                        using (var decoder = LZ4Decoder.Create(true, 64))
+                        if (msg.SubType == 6 || msg.SubType == 40)
                         {
-                            byte[] target = new byte[10240];
-                            int res = 0;
-                            if (msg.CompressContent != null)
-                                res = LZ4Codec.Decode(msg.CompressContent, 0, msg.CompressContent.Length, target, 0, target.Length);
-
-                            byte[] data = target.Skip(0).Take(res).ToArray();
-                            string xml = Encoding.UTF8.GetString(data);
-                            if (!string.IsNullOrEmpty(xml))
+                            string? path = reader.GetAttachment(WXMsgType.File, msg);
+                            if (path == null)
+                            {
+                                HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "文件不存在");
+                                continue;
+                            }
+                            else
+                            {
+                                HtmlBody += string.Format("<p class=\"content\">{0}</p><p><a href=\"{1}\">点击访问</a></p></div>", "文件:" + path, path);
+                            }
+                        }
+                        else if (msg.SubType == 19)
+                        {
+                            using (var decoder = LZ4Decoder.Create(true, 64))
                             {
-                                xml = xml.Replace("\n", "");
-                                XmlDocument xmlObj = new XmlDocument();
-                                xmlObj.LoadXml(xml);
-                                if (xmlObj.DocumentElement != null)
+                                byte[] target = new byte[10240];
+                                int res = 0;
+                                if (msg.CompressContent != null)
+                                    res = LZ4Codec.Decode(msg.CompressContent, 0, msg.CompressContent.Length, target, 0, target.Length);
+
+                                byte[] data = target.Skip(0).Take(res).ToArray();
+                                string xml = Encoding.UTF8.GetString(data);
+                                if (!string.IsNullOrEmpty(xml))
                                 {
-                                    string title = "";
-                                    string appName = "";
-                                    string url = "";
-                                    XmlNodeList? findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/title");
-                                    if (findNode != null)
+                                    xml = xml.Replace("\n", "");
+                                    XmlDocument xmlObj = new XmlDocument();
+                                    xmlObj.LoadXml(xml);
+                                    if (xmlObj.DocumentElement != null)
                                     {
-                                        if (findNode.Count > 0)
+                                        string title = "";
+                                        string record = "";
+                                        string url = "";
+                                        XmlNodeList? findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/title");
+                                        if (findNode != null)
                                         {
-                                            title = findNode[0]!.InnerText;
+                                            if (findNode.Count > 0)
+                                            {
+                                                title = findNode[0]!.InnerText;
+                                            }
                                         }
-                                    }
-                                    findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/sourcedisplayname");
-                                    if (findNode != null)
-                                    {
-                                        if (findNode.Count > 0)
+
+                                        HtmlBody += string.Format("<p class=\"content\">{0}</p>", title);
+                                        findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/recorditem");
+                                        if (findNode != null)
                                         {
-                                            appName = findNode[0]!.InnerText;
+                                            if (findNode.Count > 0)
+                                            {
+                                                XmlDocument itemObj = new XmlDocument();
+                                                itemObj.LoadXml(findNode[0]!.InnerText);
+                                                XmlNodeList? itemNode = itemObj.DocumentElement.SelectNodes("/recordinfo/datalist/dataitem");
+                                                if (itemNode.Count > 0)
+                                                {
+                                                    foreach (XmlNode node in itemNode)
+                                                    {
+                                                        string nodeMsg;
+                                                        string name = node["sourcename"].InnerText;
+                                                        if (node.Attributes["datatype"].InnerText == "1")
+                                                            nodeMsg = node["datadesc1"].InnerText;
+                                                        else if (node.Attributes["datatype"].InnerText == "2")
+                                                            nodeMsg = "不支持的消息";
+                                                        else
+                                                            nodeMsg = node["datatitle"].InnerText;
+                                                        HtmlBody += string.Format("<p class=\"content\">{0}:{1}</p>", name, nodeMsg);
+                                                    }
+                                                }
+                                            }
                                         }
                                     }
-                                    findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/url");
-                                    if (findNode != null)
+                                }
+                            }
+                        }
+                        else
+                        {
+                            using (var decoder = LZ4Decoder.Create(true, 64))
+                            {
+                                byte[] target = new byte[10240];
+                                int res = 0;
+                                if (msg.CompressContent != null)
+                                    res = LZ4Codec.Decode(msg.CompressContent, 0, msg.CompressContent.Length, target, 0, target.Length);
+
+                                byte[] data = target.Skip(0).Take(res).ToArray();
+                                string xml = Encoding.UTF8.GetString(data);
+                                if (!string.IsNullOrEmpty(xml))
+                                {
+                                    xml = xml.Replace("\n", "");
+                                    XmlDocument xmlObj = new XmlDocument();
+                                    xmlObj.LoadXml(xml);
+                                    if (xmlObj.DocumentElement != null)
                                     {
-                                        if (findNode.Count > 0)
+                                        string title = "";
+                                        string appName = "";
+                                        string url = "";
+                                        XmlNodeList? findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/title");
+                                        if (findNode != null)
+                                        {
+                                            if (findNode.Count > 0)
+                                            {
+                                                title = findNode[0]!.InnerText;
+                                            }
+                                        }
+                                        findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/sourcedisplayname");
+                                        if (findNode != null)
                                         {
-                                            url = findNode[0]!.InnerText;
+                                            if (findNode.Count > 0)
+                                            {
+                                                appName = findNode[0]!.InnerText;
+                                            }
                                         }
+                                        findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/url");
+                                        if (findNode != null)
+                                        {
+                                            if (findNode.Count > 0)
+                                            {
+                                                url = findNode[0]!.InnerText;
+                                            }
+                                        }
+                                        HtmlBody += string.Format("<p class=\"content\">{0}|{1}</p><p><a href=\"{2}\">点击访问</a></p></div>", appName, title, url);
                                     }
-                                    HtmlBody += string.Format("<p class=\"content\">{0}|{1}</p><p><a href=\"{2}\">点击访问</a></p></div>", appName, title, url);
                                 }
                             }
                         }
                     }
-                }
-                else if (msg.Type == 34)
-                {
-                    string? path = reader.GetAttachment(WXMsgType.Audio, msg);
-                    if (path == null)
+                    else if (msg.Type == 34)
+                    {
+                        string? path = reader.GetAttachment(WXMsgType.Audio, msg);
+                        if (path == null)
+                        {
+                            HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "语音不存在");
+                            continue;
+                        }
+                        HtmlBody += string.Format("<p class=\"content\"><audio controls src=\"{0}\"></audio></p></div>", path);
+                    }
+                    else
                     {
-                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "语音不存在");
-                        continue;
+                        HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "暂未支持的消息");
                     }
-                    HtmlBody += string.Format("<p class=\"content\"><audio controls src=\"{0}\"></audio></p></div>", path);
                 }
-                else
+                catch(Exception ex)
                 {
-                    HtmlBody += string.Format("<p class=\"content\">{0}</p></div>", "暂未支持的消息");
+                    err = true;
+                    File.AppendAllText("Err.log", JsonConvert.SerializeObject(msg));
+                    File.AppendAllText("Err.log", ex.ToString());
                 }
-                
+
                 msgCount++;
                 if(msgCount % 50 == 0)
                 {
@@ -202,6 +273,10 @@ namespace WechatBakTool.Export
                 streamWriter.WriteLine(HtmlBody);
                 HtmlBody = "";
                 viewModel.ExportCount = msgCount.ToString();
+                if (err)
+                {
+                    MessageBox.Show("本次导出发生了异常,部分消息被跳过,更新至最新版本后还有此问题,请将Err.log反馈给开发,谢谢。", "错误");
+                }
             }
             streamWriter.Close();
             streamWriter.Dispose();

+ 10 - 7
WechatBakTool.csproj

@@ -6,11 +6,18 @@
     <Nullable>enable</Nullable>
     <UseWPF>true</UseWPF>
     <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
-    <AssemblyVersion>0.9.6.1</AssemblyVersion>
-    <FileVersion>0.9.6.1</FileVersion>
-    <Version>0.9.6.1</Version>
+    <AssemblyVersion>0.9.6.2</AssemblyVersion>
+    <FileVersion>0.9.6.2</FileVersion>
+    <Version>0.9.6.2</Version>
   </PropertyGroup>
 
+  <ItemGroup>
+    <Compile Remove="YearReport\**" />
+    <EmbeddedResource Remove="YearReport\**" />
+    <None Remove="YearReport\**" />
+    <Page Remove="YearReport\**" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
     <PackageReference Include="jieba.NET" Version="0.42.2" />
@@ -73,8 +80,4 @@
     </None>
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="YearReport\" />
-  </ItemGroup>
-
 </Project>

+ 0 - 11
YearReport.xaml

@@ -1,11 +0,0 @@
-<Window x:Class="WechatBakTool.YearReport"
-        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-        xmlns:local="clr-namespace:WechatBakTool"
-        mc:Ignorable="d"
-        Title="YearReport" Height="660" Width="330" WindowStyle="None" WindowStartupLocation="CenterScreen" >
-    <Grid>
-    </Grid>
-</Window>

+ 0 - 27
YearReport.xaml.cs

@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Shapes;
-
-namespace WechatBakTool
-{
-    /// <summary>
-    /// YearReport.xaml 的交互逻辑
-    /// </summary>
-    public partial class YearReport : Window
-    {
-        public YearReport()
-        {
-            InitializeComponent();
-        }
-    }
-}