v0.9.4.0 Release!
1.导出HTML新增了文件与表情的支持,需要导出表情,请先使用表情预下载功能,由于略微做了一些频率限制,预下载可能会较久,请耐心等待。 2.调整了软件本身的显示逻辑 3.旧版消息工具已经移动至管理界面,如需使用,工作区,右键,管理即可
This commit is contained in:
@@ -10,6 +10,7 @@ using WechatBakTool.Model;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using WechatBakTool.ViewModel;
|
||||
using System.Security.Policy;
|
||||
|
||||
namespace WechatBakTool.Export
|
||||
{
|
||||
@@ -92,53 +93,82 @@ namespace WechatBakTool.Export
|
||||
}
|
||||
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)
|
||||
{
|
||||
#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)));
|
||||
#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)
|
||||
{
|
||||
using (var decoder = LZ4Decoder.Create(true, 64))
|
||||
if(msg.SubType == 6||msg.SubType == 19||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)
|
||||
{
|
||||
xml = xml.Replace("\n", "");
|
||||
XmlDocument xmlObj = new XmlDocument();
|
||||
xmlObj.LoadXml(xml);
|
||||
if (xmlObj.DocumentElement != null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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}</p></div>", "文件不存在");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
HtmlBody += string.Format("<p class=\"content\">{0}</p><p><a href=\"{1}\">点击访问</a></p></div>", "文件:" + path, path);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,67 +70,74 @@ namespace WechatBakTool.Export
|
||||
txtMsg = "[视频]";
|
||||
break;
|
||||
case 49:
|
||||
try
|
||||
if (msg.SubType == 6 || msg.SubType == 19 || msg.SubType == 40)
|
||||
{
|
||||
using (var decoder = LZ4Decoder.Create(true, 64))
|
||||
txtMsg = "[文件]";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
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))
|
||||
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 appName = "";
|
||||
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)
|
||||
{
|
||||
appName = findNode[0]!.InnerText;
|
||||
}
|
||||
}
|
||||
findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/url");
|
||||
if (findNode != null)
|
||||
{
|
||||
if (findNode.Count > 0)
|
||||
{
|
||||
url = findNode[0]!.InnerText;
|
||||
}
|
||||
}
|
||||
txtMsg = string.Format("{0},标题:{1},链接:{2}", appName, title, url);
|
||||
}
|
||||
findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/sourcedisplayname");
|
||||
if (findNode != null)
|
||||
else
|
||||
{
|
||||
if (findNode.Count > 0)
|
||||
{
|
||||
appName = findNode[0]!.InnerText;
|
||||
}
|
||||
txtMsg = "[分享链接出错了]";
|
||||
}
|
||||
findNode = xmlObj.DocumentElement.SelectNodes("/msg/appmsg/url");
|
||||
if (findNode != null)
|
||||
{
|
||||
if (findNode.Count > 0)
|
||||
{
|
||||
url = findNode[0]!.InnerText;
|
||||
}
|
||||
}
|
||||
txtMsg = string.Format("{0},标题:{1},链接:{2}", appName, title, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
txtMsg = "[分享链接出错了]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
txtMsg = "[分享链接出错了]";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
txtMsg = "[分享链接出错了]";
|
||||
catch
|
||||
{
|
||||
txtMsg = "[分享链接出错了]";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:WechatBakTool"
|
||||
mc:Ignorable="d" WindowStartupLocation="CenterScreen" WindowStyle="None" WindowState="Normal" Background="Transparent" AllowsTransparency="True" ResizeMode="NoResize"
|
||||
Title="Main2" Height="550" Width="950" >
|
||||
Title="WechatBakTool" Height="550" Width="950" >
|
||||
<Window.Resources>
|
||||
<Style TargetType="local:Main2">
|
||||
<!-- 设置窗体的WindowChrome -->
|
||||
|
||||
@@ -128,6 +128,7 @@ namespace WechatBakTool.Model
|
||||
public string StrTalker { get; set; } = "";
|
||||
[Column("StrContent")]
|
||||
public string StrContent { get; set; } = "";
|
||||
public string DisplayContent { get; set; } = "";
|
||||
[Column("CompressContent")]
|
||||
public byte[]? CompressContent { get; set; }
|
||||
[Column("BytesExtra")]
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
<Button Name="btn_export_all" Margin="35,110" Height="26" Width="60" Content="导出" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#2775b6" Foreground="White" BorderThickness="0" Click="btn_export_all_Click"></Button>
|
||||
<Label Content="{Binding LabelStatus}" HorizontalAlignment="Left" Margin="110,110,0,0" VerticalAlignment="Top"/>
|
||||
|
||||
<Label Margin="30,155" Content="表情包预下载" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" />
|
||||
<Button Name="btn_emoji_download" Margin="35,185" Height="26" Width="60" Content="导出" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#2775b6" Foreground="White" BorderThickness="0" Click="btn_emoji_download_Click"></Button>
|
||||
<Label Margin="30,155,0,0" Content="表情包预下载" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" />
|
||||
<Button Name="btn_emoji_download" Margin="35,185,0,0" Height="26" Width="60" Content="导出" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#2775b6" Foreground="White" BorderThickness="0" Click="btn_emoji_download_Click"></Button>
|
||||
|
||||
<Label Margin="30,225,0,0" Content="旧版分析工具" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" />
|
||||
<Button Name="btn_analyse" Margin="35,255,0,0" Height="26" Width="60" Content="打开" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#2775b6" Foreground="White" BorderThickness="0" Click="btn_analyse_Click" ></Button>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -95,8 +95,23 @@ namespace WechatBakTool.Pages
|
||||
{
|
||||
if (UserReader != null)
|
||||
{
|
||||
UserReader.PreDownloadEmoji();
|
||||
Task.Run(() =>
|
||||
{
|
||||
UserReader.PreDownloadEmoji();
|
||||
MessageBox.Show("所有表情预下载完毕");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_analyse_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UserReader == null || Main2.CurrentUserBakConfig == null)
|
||||
{
|
||||
MessageBox.Show("请先读取数据");
|
||||
return;
|
||||
}
|
||||
Analyse analyse = new Analyse(Main2.CurrentUserBakConfig, UserReader);
|
||||
analyse.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
<!-- 这里是listview滚动条的滑动块部分样式-->
|
||||
<Style x:Key="ScrollBarThumbVertical" TargetType="{x:Type Thumb}">
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
@@ -158,7 +158,7 @@
|
||||
<Grid Margin="0">
|
||||
<Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" Content="{Binding NickName}"/>
|
||||
<Label Margin="60,25,0,8" VerticalAlignment="Top" HorizontalAlignment="Left" Width="380">
|
||||
<TextBlock Text="{Binding StrContent}" TextWrapping="Wrap" />
|
||||
<TextBlock Text="{Binding DisplayContent}" TextWrapping="Wrap" />
|
||||
</Label>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@@ -215,7 +215,7 @@
|
||||
</ListView>
|
||||
<Label Content="{Binding WXContact.NickName}" HorizontalAlignment="Left" Margin="258,21,0,0" VerticalAlignment="Top"/>
|
||||
<ListView x:Name="list_msg" Margin="230,60,0,60" Background="Transparent" BorderThickness="0,1,0,1" BorderBrush="#BB2775b6" ItemTemplate="{DynamicResource MsgText}">
|
||||
|
||||
|
||||
</ListView>
|
||||
<ComboBox Name="cb_export" Width="120" Height="30" Style="{StaticResource ComboBoxStyle}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="30,15" ItemsSource="{Binding ExportItems}" SelectedItem="{Binding SelectExportItem}" DisplayMemberPath="Name" SelectedValuePath="Value" IsEnabled="{Binding SelectContact}" Background="#2775b6" />
|
||||
<Button x:Name="btn_open_workspace" Width="80" Height="30" Style="{StaticResource ButtonStyle}" Content="打开文件夹" BorderBrush="Transparent" BorderThickness="0" Background="#2775b6" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,390,15" Click="btn_open_workspace_Click">
|
||||
@@ -225,7 +225,7 @@
|
||||
</Style>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
<Button x:Name="btn_analyse" Width="80" Height="30" Style="{StaticResource ButtonStyle}" Content="旧版消息工具" BorderBrush="Transparent" BorderThickness="0" Background="#2775b6" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,292,15" Click="btn_analyse_Click" >
|
||||
<Button x:Name="btn_pre_emoji" Width="80" Height="30" Style="{StaticResource ButtonStyle}" Content="表情预下载" BorderBrush="Transparent" BorderThickness="0" Background="#2775b6" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,292,15" IsEnabled="{Binding SelectContact}" Click="btn_pre_emoji_Click" >
|
||||
<Button.Resources>
|
||||
<Style TargetType="{x:Type Border}">
|
||||
<Setter Property="CornerRadius" Value="3"/>
|
||||
|
||||
@@ -114,23 +114,10 @@ namespace WechatBakTool.Pages
|
||||
Process.Start("explorer.exe ", Main2.CurrentUserBakConfig!.UserWorkspacePath);
|
||||
}
|
||||
|
||||
private void btn_analyse_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UserReader == null || Main2.CurrentUserBakConfig == null)
|
||||
{
|
||||
MessageBox.Show("请先读取数据");
|
||||
return;
|
||||
}
|
||||
Analyse analyse = new Analyse(Main2.CurrentUserBakConfig, UserReader);
|
||||
analyse.Show();
|
||||
}
|
||||
|
||||
private void Export_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
|
||||
|
||||
if (ViewModel.WXContact == null || UserReader == null)
|
||||
{
|
||||
MessageBox.Show("请选择联系人", "错误");
|
||||
@@ -170,5 +157,16 @@ namespace WechatBakTool.Pages
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void btn_pre_emoji_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if(UserReader != null && ViewModel.WXContact != null)
|
||||
{
|
||||
Task.Run(() => {
|
||||
UserReader.PreDownloadEmoji(ViewModel.WXContact.UserName);
|
||||
MessageBox.Show("用户所有表情预下载完毕");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
README.md
14
README.md
@@ -24,12 +24,16 @@
|
||||
<br/>
|
||||
|
||||
### 免责声明
|
||||
|
||||
**本项目仅供学习使用,严禁商业使用**<br/>
|
||||
**本项目完全免费,问你要钱的都是骗子**<br/>
|
||||
**使用本项目初衷是作者研究微信数据库的运行使用,您使用本软件导致的后果,包含但不限于数据损坏,记录丢失等问题,作者不承担相关责任。**<br/>
|
||||
**因软件特殊性质,请在使用时获得微信账号所有人授权。**
|
||||
<br/>
|
||||
|
||||
### 隐私声明
|
||||
**本项目不会上传任何你的数据至任何第三方系统**<br/>
|
||||
**如果发生任何回传行为,请检查是否为第三方修改版本**<br/>
|
||||
|
||||
### 近期开发规划
|
||||
本项目技术栈为:
|
||||
C# + .NET6.0 + WPF MVVM(目前MVVM不是特别完全!莫喷!) <br/>
|
||||
@@ -40,6 +44,14 @@ C# + .NET6.0 + WPF MVVM(目前MVVM不是特别完全!莫喷!) <br/>
|
||||
- [ ] 手动模式(合适离线分析)
|
||||
<br/>
|
||||
|
||||
### 部分问题
|
||||
Q:支持手机端吗<br/>
|
||||
A:<b>在手机端</b>使用迁移功能即可,路径:我->设置->聊天->聊天记录迁移与备份->迁移<br/>
|
||||
<br/>
|
||||
Q:怎么导出全部的记录<br/>
|
||||
A:工作区->右键->管理,就见了。<br/>
|
||||
<br/>
|
||||
|
||||
### 使用说明
|
||||
**本说明为新版本说明,即将发版**<br/>
|
||||
0.安装.NET Desktop Runtime(如已经安装忽略)<br/>
|
||||
|
||||
110
WXUserReader.cs
110
WXUserReader.cs
@@ -21,6 +21,7 @@ using System.Windows;
|
||||
using System.Net.Http;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace WechatBakTool
|
||||
{
|
||||
@@ -37,6 +38,7 @@ namespace WechatBakTool
|
||||
UserBakConfig = userBakConfig;
|
||||
LoadDB(path);
|
||||
InitCache();
|
||||
EmojiCacheInit();
|
||||
}
|
||||
|
||||
public void LoadDB(string path)
|
||||
@@ -107,7 +109,7 @@ namespace WechatBakTool
|
||||
}
|
||||
}
|
||||
|
||||
public void PreDownloadEmoji()
|
||||
public void PreDownloadEmoji(string username = "")
|
||||
{
|
||||
if (UserBakConfig == null)
|
||||
return;
|
||||
@@ -115,11 +117,10 @@ namespace WechatBakTool
|
||||
HttpClientHandler handler = new HttpClientHandler() { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate };
|
||||
HttpClient httpClient = new HttpClient(handler);
|
||||
|
||||
List<WXMsg> msgs = GetTypeMsg("47");
|
||||
List<WXMsg> msgs = GetTypeMsg("47", username);
|
||||
int i = 0;
|
||||
|
||||
EmojiCacheInit();
|
||||
|
||||
// 下载前的Emoji Cache不用做了,在Init的时候已经做了
|
||||
foreach (var msg in msgs)
|
||||
{
|
||||
i++;
|
||||
@@ -150,14 +151,18 @@ namespace WechatBakTool
|
||||
url = item != null ? item.InnerText : "";
|
||||
|
||||
if (EmojiCache.ContainsKey(md5))
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
|
||||
}
|
||||
if (url == "")
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string path = Path.Combine(UserBakConfig.UserWorkspacePath, "Emoji", md5 + ".jpg");
|
||||
string path = Path.Combine(UserBakConfig.UserWorkspacePath, "Emoji", md5 + ".gif");
|
||||
try
|
||||
{
|
||||
HttpResponseMessage res = httpClient.GetAsync(url).Result;
|
||||
@@ -182,6 +187,9 @@ namespace WechatBakTool
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 下载完成后可能变化,检查一下
|
||||
EmojiCacheInit();
|
||||
}
|
||||
|
||||
public byte[]? GetHeadImgCahce(string username)
|
||||
@@ -298,7 +306,7 @@ namespace WechatBakTool
|
||||
return con.Query<WXChatRoom>(query);
|
||||
}
|
||||
|
||||
public List<WXMsg> GetTypeMsg(string type)
|
||||
public List<WXMsg> GetTypeMsg(string type,string username)
|
||||
{
|
||||
List<WXMsg> tmp = new List<WXMsg>();
|
||||
for (int i = 0; i <= 99; i++)
|
||||
@@ -307,8 +315,17 @@ namespace WechatBakTool
|
||||
if (con == null)
|
||||
return tmp;
|
||||
|
||||
string query = "select * from MSG where Type=?";
|
||||
List<WXMsg> wXMsgs = con.Query<WXMsg>(query, type);
|
||||
List<WXMsg> wXMsgs;
|
||||
if (username == "")
|
||||
{
|
||||
string query = "select * from MSG where Type=?";
|
||||
wXMsgs = con.Query<WXMsg>(query, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
string query = "select * from MSG where Type=? and StrTalker = ?";
|
||||
wXMsgs = con.Query<WXMsg>(query, type, username);
|
||||
}
|
||||
tmp.AddRange(wXMsgs);
|
||||
}
|
||||
return tmp;
|
||||
@@ -351,9 +368,9 @@ namespace WechatBakTool
|
||||
else
|
||||
w.NickName = contact.NickName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 群聊处理
|
||||
if (uid.Contains("@chatroom"))
|
||||
{
|
||||
string userId = "";
|
||||
@@ -393,20 +410,37 @@ namespace WechatBakTool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 发送人名字处理
|
||||
if (w.IsSender)
|
||||
w.NickName = "我";
|
||||
|
||||
w.DisplayContent = w.StrContent;
|
||||
// 额外格式处理
|
||||
if (w.Type != 1)
|
||||
{
|
||||
if (w.Type == 10000)
|
||||
{
|
||||
w.Type = 1;
|
||||
w.NickName = "系统消息";
|
||||
w.StrContent = w.StrContent.Replace("<revokemsg>", "").Replace("</revokemsg>", "");
|
||||
w.DisplayContent = w.StrContent.Replace("<revokemsg>", "").Replace("</revokemsg>", "");
|
||||
}
|
||||
else if (w.Type == 49 && (w.SubType == 6 || w.SubType == 19 || w.SubType == 40))
|
||||
{
|
||||
WXSessionAttachInfo? attachInfos = GetWXMsgAtc(w);
|
||||
if (attachInfos == null)
|
||||
{
|
||||
w.DisplayContent = "附件不存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
w.DisplayContent = Path.Combine(UserBakConfig!.UserResPath, attachInfos.attachPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w.StrContent = "[界面未支持格式]Type=" + w.Type;
|
||||
w.DisplayContent = "[界面未支持格式]Type=" + w.Type;
|
||||
}
|
||||
}
|
||||
tmp.Add(w);
|
||||
@@ -481,9 +515,10 @@ namespace WechatBakTool
|
||||
if (!Directory.Exists(tmpPath))
|
||||
Directory.CreateDirectory(tmpPath);
|
||||
|
||||
// 这部分是查找
|
||||
// 如果是图片和视频,从附件库中搜索
|
||||
string? path = null;
|
||||
if (type == WXMsgType.Image || type == WXMsgType.Video)
|
||||
if (type == WXMsgType.Image || type == WXMsgType.Video || type == WXMsgType.File)
|
||||
{
|
||||
WXSessionAttachInfo? atcInfo = GetWXMsgAtc(msg);
|
||||
if (atcInfo == null)
|
||||
@@ -507,39 +542,61 @@ namespace WechatBakTool
|
||||
}
|
||||
path = tmp_file_path;
|
||||
}
|
||||
else if (type == WXMsgType.Emoji)
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.LoadXml(msg.StrContent);
|
||||
XmlNode? node = xmlDocument.SelectSingleNode("/msg/emoji");
|
||||
if (node != null)
|
||||
{
|
||||
if (node.Attributes != null)
|
||||
{
|
||||
XmlNode? item = node.Attributes.GetNamedItem("md5");
|
||||
string md5 = item != null ? item.InnerText : "";
|
||||
if (EmojiCache.ContainsKey(md5))
|
||||
{
|
||||
path = string.Format("Emoji\\{0}.gif", md5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
return null;
|
||||
|
||||
// 这部分是解密
|
||||
// 获取到原路径后,开始进行解密转移,只有图片和语音需要解密,解密后是直接归档目录
|
||||
if(type == WXMsgType.Image || type== WXMsgType.Audio)
|
||||
if (type == WXMsgType.Image || type == WXMsgType.Audio)
|
||||
{
|
||||
path = DecryptAttachment(type, path);
|
||||
}
|
||||
else if (type == WXMsgType.Video)
|
||||
else if (type == WXMsgType.Video || type == WXMsgType.File)
|
||||
{
|
||||
string video_dir = Path.Combine(UserBakConfig.UserWorkspacePath, "Video");
|
||||
if(!Directory.Exists(video_dir))
|
||||
Directory.CreateDirectory(video_dir);
|
||||
string to_dir;
|
||||
if (type == WXMsgType.Video)
|
||||
to_dir = Path.Combine(UserBakConfig.UserWorkspacePath, "Video");
|
||||
else
|
||||
to_dir = Path.Combine(UserBakConfig.UserWorkspacePath, "File");
|
||||
if (!Directory.Exists(to_dir))
|
||||
Directory.CreateDirectory(to_dir);
|
||||
FileInfo fileInfo = new FileInfo(path);
|
||||
// 目标视频路径
|
||||
string video_file_path = Path.Combine(video_dir, fileInfo.Name);
|
||||
string to_file_path = Path.Combine(to_dir, fileInfo.Name);
|
||||
// 视频的路径是相对路径,需要加上资源目录
|
||||
path = Path.Combine(UserBakConfig.UserResPath, path);
|
||||
// 原文件存在,目标不存在
|
||||
if (!File.Exists(video_file_path) && File.Exists(path))
|
||||
if (!File.Exists(to_file_path) && File.Exists(path))
|
||||
{
|
||||
// 复制
|
||||
File.Copy(path, video_file_path);
|
||||
path = video_file_path;
|
||||
File.Copy(path, to_file_path);
|
||||
path = to_file_path;
|
||||
}
|
||||
else if (File.Exists(video_file_path))
|
||||
else if (File.Exists(to_file_path))
|
||||
{
|
||||
path = video_file_path;
|
||||
path = to_file_path;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
@@ -611,5 +668,6 @@ namespace WechatBakTool
|
||||
Video = 1,
|
||||
Audio = 2,
|
||||
File = 3,
|
||||
Emoji = 4,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<AssemblyVersion>0.9.3.0</AssemblyVersion>
|
||||
<FileVersion>0.9.3.0</FileVersion>
|
||||
<Version>0.9.3.0</Version>
|
||||
<AssemblyVersion>0.9.4.0</AssemblyVersion>
|
||||
<FileVersion>0.9.4.0</FileVersion>
|
||||
<Version>0.9.4.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user