Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 33 additions & 28 deletions WechatExport/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public Form1()
private void LoadManifests()
{
comboBox1.Items.Clear();
string s = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
s = MyPath.Combine(s, "Apple Computer", "MobileSync", "Backup");
string s = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
s = MyPath.Combine(s, "Apple", "MobileSync", "Backup");
try
{
DirectoryInfo d = new DirectoryInfo(s);
Expand Down Expand Up @@ -232,40 +232,45 @@ void Run()
}
AddLog("找到" + friendcount + "个好友/聊天室");
AddLog("查找对话");
wechat.GetChatSessions(conn, out List<string> chats);
AddLog("找到" + chats.Count + "个对话");
var count = wechat.GetChatSessions(conn, userBase, out Dictionary<SQLiteConnection, List<string>> chats);
AddLog("找到" + count + "个对话");
var emojidown = new HashSet<DownloadTask>();
var chatList = new List<DisplayItem>();
foreach (var chat in chats)
foreach (var pair in chats)
{
var hash = chat;
string displayname = chat, id = displayname;
Friend friend = null;
if (friends.ContainsKey(hash))
var c = pair.Key;
foreach (var chat in pair.Value)
{
friend = friends[hash];
displayname = friend.DisplayName();
AddLog("处理与" + displayname + "的对话");
id = friend.ID();
}
else AddLog("未找到好友信息,用默认名字代替");
if (radioButton4.Checked)
{
if (wechat.SaveTextRecord(conn, Path.Combine(userSaveBase, id + ".txt"), displayname, id, myself, chat, friend, friends, out int count)) AddLog("成功处理" + count + "条");
else AddLog("失败");
}
else if(radioButton3.Checked)
{
if (wechat.SaveHtmlRecord(conn, userBase, userSaveBase, displayname, id, myself, chat, friend, friends, out int count, out HashSet<DownloadTask> _emojidown))
var hash = chat;
string displayname = chat, id = displayname;
Friend friend = null;
if (friends.ContainsKey(hash))
{
friend = friends[hash];
displayname = friend.DisplayName();
AddLog("处理与" + displayname + "的对话");
id = friend.ID();
}
else AddLog("未找到好友信息,用默认名字代替");
if (radioButton4.Checked)
{
AddLog("成功处理" + count + "条");
chatList.Add(new DisplayItem() { pic = "Portrait/" + (friend != null ? friend.FindPortrait() : "DefaultProfileHead@2x.png"), text = displayname, link = id + ".html" });
if (wechat.SaveTextRecord(c, Path.Combine(userSaveBase, id + ".txt"), displayname, id, myself, chat, friend, friends, out int msgcnt)) AddLog("成功处理" + msgcnt + "条");
else AddLog("失败");
}
else if (radioButton3.Checked)
{
if (wechat.SaveHtmlRecord(c, userBase, userSaveBase, displayname, id, myself, chat, friend, friends, out int msgcnt, out HashSet<DownloadTask> _emojidown))
{
AddLog("成功处理" + msgcnt + "条");
chatList.Add(new DisplayItem() { pic = "Portrait/" + (friend != null ? friend.FindPortrait() : "DefaultProfileHead@2x.png"), text = displayname, link = id + ".html" });
}
else AddLog("失败");
emojidown.UnionWith(_emojidown);
}
else AddLog("失败");
emojidown.UnionWith(_emojidown);
}

c.Close();
}
conn.Close();
if(radioButton3.Checked) wechat.MakeListHTML(chatList, Path.Combine(userSaveBase, "聊天记录.html"));
var portraitdir = Path.Combine(userSaveBase, "Portrait");
Directory.CreateDirectory(portraitdir);
Expand Down
82 changes: 79 additions & 3 deletions WechatExport/wechat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ public bool OpenWCDBContact(string userBase, out SQLiteConnection conn)
return succ;
}


public bool OpenMessageSqlite(string userBase, out SQLiteConnection conn)
{
bool succ = false;
conn = null;
try
{
conn = new SQLiteConnection
{
ConnectionString = "data source=" + GetBackupFilePath(MyPath.Combine(userBase, "DB", "WCDB_Contact.sqlite")) + ";version=3"
};
conn.Open();
succ = true;
}
catch (Exception) { }
return succ;
}

public bool GetUserBasics(string uid, string userBase, out Friend friend)
{
friend = new Friend() { UsrName = uid, NickName = "我", alias = null, PortraitRequired=true };
Expand Down Expand Up @@ -244,6 +262,50 @@ public bool GetChatSessions(SQLiteConnection conn, out List<string> sessions)
return succ;
}

public int GetChatSessions(SQLiteConnection conn, string userBase, out Dictionary<SQLiteConnection, List<string>> sessions)
{
sessions = new Dictionary<SQLiteConnection, List<string>>();
if (!GetChatSessions(conn, out List<string> chats))
{
return 0;
}
sessions.Add(conn, chats);

int i = 0, count = chats.Count;
while (true)
{
i++;
string msgfilename = GetBackupFilePath(MyPath.Combine(userBase, "DB", "message_" + i + ".sqlite"));
if (!File.Exists(msgfilename))
{
break;
}

SQLiteConnection msgconn;
try
{
msgconn = new SQLiteConnection
{
ConnectionString = "data source=" + msgfilename + ";version=3"
};
msgconn.Open();
}
catch (Exception e)
{
System.Console.Out.Write(e);
return -1;
}

if (!GetChatSessions(msgconn, out chats))
{
return -1;
}
count += chats.Count;
sessions.Add(msgconn, chats);
}
return count;
}

public bool SaveTextRecord(SQLiteConnection conn, string path, string displayname, string id, Friend myself, string table, Friend friend, Dictionary<string, Friend> friends, out int count)
{
bool succ = false;
Expand Down Expand Up @@ -287,7 +349,7 @@ public bool SaveTextRecord(SQLiteConnection conn, string path, string displaynam
}
if (type == 34) message = "[语音]";
else if (type == 47) message = "[表情]";
else if (type == 62) message = "[小视频]";
else if (type == 62 || type == 43) message = "[小视频]";
else if (type == 50) message = "[视频/语音通话]";
else if (type == 3) message = "[图片]";
else if (type == 48) message = "[位置]";
Expand Down Expand Up @@ -414,7 +476,7 @@ public bool SaveHtmlRecord(SQLiteConnection conn, string userBase, string path,s
}
else message = "[表情]";
}
else if (type == 62)
else if (type == 62 || type == 43)
{
var hasthum = RequireResource(MyPath.Combine(userBase, "Video", table, msgid + ".video_thum"), Path.Combine(assetsdir, msgid + "_thum.jpg"));
var hasvid = RequireResource(MyPath.Combine(userBase, "Video", table, msgid + ".mp4"), Path.Combine(assetsdir, msgid + ".mp4"));
Expand Down Expand Up @@ -446,7 +508,21 @@ public bool SaveHtmlRecord(SQLiteConnection conn, string userBase, string path,s
if (message.Contains("<type>2001<")) message = "[红包]";
else if (message.Contains("<type>2000<")) message = "[转账]";
else if (message.Contains("<type>17<")) message = "[实时位置共享]";
else if (message.Contains("<type>6<")) message = "[文件]";
else if (message.Contains("<type>6<"))
{
var match1 = Regex.Match(message, @"<fileext>(.+?)<\/fileext>");
var match2 = Regex.Match(message, @"<title>(.+?)<\/title>");
if (match1.Success && match2.Success)
{
var hasfile = RequireResource(MyPath.Combine(userBase, "OpenData", table, msgid + "." + match1.Groups[1].Value), Path.Combine(assetsdir, match2.Groups[1].Value));
if (hasfile) message = "<a href=\"" + id + "_files/" + match2.Groups[1].Value + "\">" + match2.Groups[1].Value + "</a>";
else message = match2.Groups[1].Value + "(文件丢失)";
}
else
{
message = "[文件]";
}
}
else
{
var match1 = Regex.Match(message, @"<title>(.+?)<\/title>");
Expand Down