[+] 新的安装器

This commit is contained in:
辉鸭蛋 2024-09-29 00:32:03 +08:00
parent 82b52efaa1
commit 64087e6165
7 changed files with 367 additions and 52 deletions

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ namespace RevokeMsgPatcher
{ {
Apps = AppConfig(), Apps = AppConfig(),
LatestVersion = "1.8", LatestVersion = "1.8",
PatchVersion = 20240615, PatchVersion = 20240928,
Notice = "", Notice = "",
NoticeUrl = "", NoticeUrl = "",
}; };
@ -1373,7 +1373,7 @@ namespace RevokeMsgPatcher
{ {
Name="QQ.exe", Name="QQ.exe",
StartVersion="9.9.10.00000", StartVersion="9.9.10.00000",
EndVersion="", EndVersion="9.9.15.00000",
ReplacePatterns = new List<ReplacePattern> ReplacePatterns = new List<ReplacePattern>
{ {
new ReplacePattern new ReplacePattern

View File

@ -36,6 +36,9 @@
this.btnRestore = new System.Windows.Forms.Button(); this.btnRestore = new System.Windows.Forms.Button();
this.txtQQNTPath = new System.Windows.Forms.TextBox(); this.txtQQNTPath = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.btnChoose = new System.Windows.Forms.Button();
this.splitter1 = new System.Windows.Forms.Splitter();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout();
@ -56,13 +59,15 @@
// //
// splitContainer1.Panel2 // splitContainer1.Panel2
// //
this.splitContainer1.Panel2.Controls.Add(this.btnChoose);
this.splitContainer1.Panel2.Controls.Add(this.label2);
this.splitContainer1.Panel2.Controls.Add(this.btnCheckUpdateAll); this.splitContainer1.Panel2.Controls.Add(this.btnCheckUpdateAll);
this.splitContainer1.Panel2.Controls.Add(this.btnPath); this.splitContainer1.Panel2.Controls.Add(this.btnPath);
this.splitContainer1.Panel2.Controls.Add(this.btnRestore); this.splitContainer1.Panel2.Controls.Add(this.btnRestore);
this.splitContainer1.Panel2.Controls.Add(this.txtQQNTPath); this.splitContainer1.Panel2.Controls.Add(this.txtQQNTPath);
this.splitContainer1.Panel2.Controls.Add(this.label1); this.splitContainer1.Panel2.Controls.Add(this.label1);
this.splitContainer1.Size = new System.Drawing.Size(446, 284); this.splitContainer1.Size = new System.Drawing.Size(446, 280);
this.splitContainer1.SplitterDistance = 193; this.splitContainer1.SplitterDistance = 161;
this.splitContainer1.TabIndex = 0; this.splitContainer1.TabIndex = 0;
// //
// dataGridView1 // dataGridView1
@ -77,12 +82,13 @@
this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true; this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowTemplate.Height = 23; this.dataGridView1.RowTemplate.Height = 23;
this.dataGridView1.Size = new System.Drawing.Size(446, 193); this.dataGridView1.Size = new System.Drawing.Size(446, 161);
this.dataGridView1.TabIndex = 2; this.dataGridView1.TabIndex = 2;
// //
// btnCheckUpdateAll // btnCheckUpdateAll
// //
this.btnCheckUpdateAll.Location = new System.Drawing.Point(12, 49); this.btnCheckUpdateAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnCheckUpdateAll.Location = new System.Drawing.Point(12, 80);
this.btnCheckUpdateAll.Name = "btnCheckUpdateAll"; this.btnCheckUpdateAll.Name = "btnCheckUpdateAll";
this.btnCheckUpdateAll.Size = new System.Drawing.Size(75, 23); this.btnCheckUpdateAll.Size = new System.Drawing.Size(75, 23);
this.btnCheckUpdateAll.TabIndex = 4; this.btnCheckUpdateAll.TabIndex = 4;
@ -93,7 +99,7 @@
// btnPath // btnPath
// //
this.btnPath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnPath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnPath.Location = new System.Drawing.Point(359, 52); this.btnPath.Location = new System.Drawing.Point(359, 80);
this.btnPath.Name = "btnPath"; this.btnPath.Name = "btnPath";
this.btnPath.Size = new System.Drawing.Size(75, 23); this.btnPath.Size = new System.Drawing.Size(75, 23);
this.btnPath.TabIndex = 3; this.btnPath.TabIndex = 3;
@ -104,7 +110,7 @@
// btnRestore // btnRestore
// //
this.btnRestore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnRestore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnRestore.Location = new System.Drawing.Point(278, 52); this.btnRestore.Location = new System.Drawing.Point(278, 80);
this.btnRestore.Name = "btnRestore"; this.btnRestore.Name = "btnRestore";
this.btnRestore.Size = new System.Drawing.Size(75, 23); this.btnRestore.Size = new System.Drawing.Size(75, 23);
this.btnRestore.TabIndex = 2; this.btnRestore.TabIndex = 2;
@ -116,28 +122,57 @@
// //
this.txtQQNTPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) this.txtQQNTPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.txtQQNTPath.Location = new System.Drawing.Point(97, 14); this.txtQQNTPath.Location = new System.Drawing.Point(97, 53);
this.txtQQNTPath.Name = "txtQQNTPath"; this.txtQQNTPath.Name = "txtQQNTPath";
this.txtQQNTPath.Size = new System.Drawing.Size(337, 21); this.txtQQNTPath.Size = new System.Drawing.Size(293, 21);
this.txtQQNTPath.TabIndex = 1; this.txtQQNTPath.TabIndex = 1;
// //
// label1 // label1
// //
this.label1.AutoSize = true; this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 17); this.label1.Location = new System.Drawing.Point(12, 56);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(89, 12); this.label1.Size = new System.Drawing.Size(89, 12);
this.label1.TabIndex = 0; this.label1.TabIndex = 0;
this.label1.Text = "QQNT安装路径"; this.label1.Text = "QQNT安装路径";
// //
// label2
//
this.label2.Location = new System.Drawing.Point(12, 11);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(424, 26);
this.label2.TabIndex = 5;
this.label2.Text = "这只是一个安装器,所有功能都来自于 LiteLoaderQQNT 和其相关插件。";
//
// btnChoose
//
this.btnChoose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnChoose.Location = new System.Drawing.Point(396, 53);
this.btnChoose.Name = "btnChoose";
this.btnChoose.Size = new System.Drawing.Size(38, 23);
this.btnChoose.TabIndex = 6;
this.btnChoose.Text = "...";
this.btnChoose.UseVisualStyleBackColor = true;
this.btnChoose.Click += new System.EventHandler(this.btnChoose_Click);
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(0, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 280);
this.splitter1.TabIndex = 1;
this.splitter1.TabStop = false;
//
// FormLiteLoaderQQNT // FormLiteLoaderQQNT
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(446, 284); this.ClientSize = new System.Drawing.Size(446, 280);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.splitContainer1); this.Controls.Add(this.splitContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FormLiteLoaderQQNT"; this.Name = "FormLiteLoaderQQNT";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "LiteLoaderQQNT安装器"; this.Text = "LiteLoaderQQNT安装器";
this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false);
@ -158,5 +193,8 @@
private System.Windows.Forms.Button btnRestore; private System.Windows.Forms.Button btnRestore;
private System.Windows.Forms.TextBox txtQQNTPath; private System.Windows.Forms.TextBox txtQQNTPath;
private System.Windows.Forms.Button btnCheckUpdateAll; private System.Windows.Forms.Button btnCheckUpdateAll;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button btnChoose;
private System.Windows.Forms.Splitter splitter1;
} }
} }

View File

@ -2,13 +2,18 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Xml.Linq;
using Newtonsoft.Json;
using RevokeMsgPatcher.Model; using RevokeMsgPatcher.Model;
using RevokeMsgPatcher.Modifier;
using RevokeMsgPatcher.Utils;
namespace RevokeMsgPatcher.Forms namespace RevokeMsgPatcher.Forms
{ {
@ -20,6 +25,7 @@ namespace RevokeMsgPatcher.Forms
{ {
InitializeComponent(); InitializeComponent();
InitializeDataGridView(); InitializeDataGridView();
txtQQNTPath.Text = FindInstallPath();
} }
@ -164,12 +170,276 @@ namespace RevokeMsgPatcher.Forms
private void btnRestore_Click(object sender, EventArgs e) private void btnRestore_Click(object sender, EventArgs e)
{ {
string installPath = txtQQNTPath.Text;
if (!IsAllFilesExist(installPath))
{
MessageBox.Show("请选择正确的QQNT安装路径!");
return;
}
try
{
string appPath = GetAppPath(installPath);
RestoreDll(installPath);
RestorePackageJson(appPath);
MessageBox.Show("LiteLoaderQQNT 还原成功!");
}
catch (Exception ex)
{
MessageBox.Show(
$@"
{ex.Source}
--
{ex.StackTrace}
--
{ex.Message}
"
);
}
} }
private void RestoreDll(string installPath)
{
string destPath = Path.Combine(installPath, "dbghelp.dll");
if (File.Exists(destPath))
{
File.Delete(destPath);
}
}
private void RestorePackageJson(string appPath)
{
string packageJsonPath = Path.Combine(appPath, "package.json");
string backupPath = Path.Combine(appPath, "package.json.h.bak");
if (File.Exists(backupPath))
{
File.Copy(backupPath, packageJsonPath, true);
}
else
{
throw new Exception($"在路径{appPath}下未找到package.json.h.bak备份文件请确认是否通过本软件安装过 LiteLoaderQQNT");
}
}
/// <summary>
/// 打补丁
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPath_Click(object sender, EventArgs e) private void btnPath_Click(object sender, EventArgs e)
{ {
string installPath = txtQQNTPath.Text;
if (!IsAllFilesExist(installPath))
{
MessageBox.Show("请选择正确的QQNT安装路径!");
return;
}
try
{
string appPath = GetAppPath(installPath);
MoveDll(installPath);
CreateLauncherFile(appPath);
ModifyPackageJson(appPath);
MessageBox.Show("LiteLoaderQQNT 安装成功!");
}
catch (IOException ex)
{
MessageBox.Show(
$@"
QQNT
LiteLoaderQQNT {ex.Source}
--
{ex.StackTrace}
--
{ex.Message}
"
);
}
catch (Exception ex)
{
MessageBox.Show(
$@"
LiteLoaderQQNT {ex.Source}
--
{ex.StackTrace}
--
{ex.Message}
"
);
}
}
private void MoveDll(string installPath)
{
string fileName = "dbghelp.dll";
string destPath = Path.Combine(installPath, fileName);
if (File.Exists(destPath))
{
File.Delete(destPath);
}
File.Copy(Path.Combine(Application.StartupPath, "Public", fileName), destPath);
}
/// <summary>
/// 查看 QQNT 根目录(txtQQNTPath.Text),是否存在 versions 文件夹 是,则路径为 QQNT\versions\版本号\resources\app 否,则路径为 QQNT\resources\app
/// </summary>
/// <param name="installPath"></param>
/// <returns></returns>
private string GetAppPath(string installPath)
{
string versionsPath = Path.Combine(installPath, "versions");
if (Directory.Exists(versionsPath))
{
var versionDirectories = Directory.GetDirectories(versionsPath);
if (versionDirectories.Length > 0)
{
// 选择最新的版本
string latestVersion = versionDirectories
.Select(Path.GetFileName)
.OrderByDescending(v => new
{
MainVersion = new Version(v.Split('-')[0]),
SubVersion = int.Parse(v.Split('-')[1])
})
.FirstOrDefault();
if (latestVersion != null)
{
return Path.Combine(versionsPath, latestVersion, "resources", "app");
}
}
}
return Path.Combine(installPath, "resources", "app");
}
/// <summary>
/// 创建 app/app_launcher/liteloader.h.js 文件,写入 require(String.raw*) 其中 * 为 LiteLoaderQQNT 的路径
/// </summary>
/// <param name="appPath"></param>
/// <exception cref="Exception"></exception>
private void CreateLauncherFile(string appPath)
{
string launcherDir = Path.Combine(appPath, "app_launcher");
if (!Directory.Exists(launcherDir))
{
throw new Exception($"在路径{appPath}下未找到app_launcher文件夹");
}
string launcherFilePath = Path.Combine(launcherDir, "liteloader.h.js");
// if (File.Exists(launcherFilePath))
// {
// Debug.WriteLine("已经创建过liteloader.h.js文件");
// return;
// }
string liteLoaderPath = Path.Combine(Application.StartupPath, "LiteLoaderQQNT");
string content = $"require(String.raw`{liteLoaderPath}`);";
File.WriteAllText(launcherFilePath, content, Encoding.UTF8);
}
/// <summary>
/// 修改 app/package.json 文件,将 main 后面的路径改为 ./app_launcher/liteloader.h.js
/// </summary>
/// <param name="appPath"></param>
/// <exception cref="Exception"></exception>
private void ModifyPackageJson(string appPath)
{
string packageJsonPath = Path.Combine(appPath, "package.json");
if (File.Exists(packageJsonPath))
{
string json = File.ReadAllText(packageJsonPath);
dynamic jsonObj = JsonConvert.DeserializeObject(json);
if (jsonObj.main != null)
{
var s = (string)jsonObj.main;
if (s.Contains("liteloader.h.js"))
{
Debug.WriteLine("已经修改过package.json文件");
return;
}
}
// 备份
File.Copy(packageJsonPath, Path.Combine(appPath, "package.json.h.bak"), true);
// 修改
jsonObj.main = "./app_launcher/liteloader.h.js";
string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
File.WriteAllText(packageJsonPath, output);
}
else
{
throw new Exception($"在路径{appPath}下未找到package.json文件");
}
}
private void btnChoose_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "请选择安装路径";
if (dialog.ShowDialog() == DialogResult.OK)
{
if (string.IsNullOrEmpty(dialog.SelectedPath) || !IsAllFilesExist(dialog.SelectedPath))
{
MessageBox.Show("无法找到此应用的关键文件,请选择正确的安装路径!");
}
else
{
txtQQNTPath.Text = dialog.SelectedPath;
}
}
}
/// <summary>
/// 自动寻找获取QQNT安装路径
/// </summary>
/// <returns></returns>
public string FindInstallPath()
{
try
{
string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ");
if (!string.IsNullOrEmpty(installPath))
{
installPath = Path.GetDirectoryName(installPath);
if (IsAllFilesExist(installPath))
{
return installPath;
}
}
installPath = PathUtil.FindInstallPathFromRegistry("QQNT");
if (!IsAllFilesExist(installPath))
{
List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT");
foreach (string defaultPath in defaultPathList)
{
if (IsAllFilesExist(defaultPath))
{
return defaultPath;
}
}
}
else
{
return installPath;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
private bool IsAllFilesExist(string installPath)
{
return File.Exists(Path.Combine(installPath, "QQ.exe"));
} }
} }
} }

View File

@ -116,7 +116,14 @@ namespace RevokeMsgPatcher.Model
} }
else else
{ {
UpdateStatus("未检查"); if (NameLink.Contains("QQNTFileVerifyPatch"))
{
UpdateStatus("无需更新");
}
else
{
UpdateStatus("未检查");
}
} }
} }
@ -125,7 +132,6 @@ namespace RevokeMsgPatcher.Model
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
var response = await client.GetAsync(VersionJsonUrl); var response = await client.GetAsync(VersionJsonUrl);
Debug.WriteLine(response.Content);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var json = await response.Content.ReadAsStringAsync(); var json = await response.Content.ReadAsStringAsync();

View File

@ -22,41 +22,42 @@ namespace RevokeMsgPatcher.Modifier
/// <returns></returns> /// <returns></returns>
public override string FindInstallPath() public override string FindInstallPath()
{ {
try return "请在新弹出的窗口内进行 LiteLoaderQQNT 的安装与更新!";
{ // try
string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ"); // {
if (!string.IsNullOrEmpty(installPath)) // string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ");
{ // if (!string.IsNullOrEmpty(installPath))
installPath = Path.GetDirectoryName(installPath); // {
if (IsAllFilesExist(installPath)) // installPath = Path.GetDirectoryName(installPath);
{ // if (IsAllFilesExist(installPath))
return installPath; // {
} // return installPath;
} // }
// }
installPath = PathUtil.FindInstallPathFromRegistry("QQNT"); //
if (!IsAllFilesExist(installPath)) // installPath = PathUtil.FindInstallPathFromRegistry("QQNT");
{ // if (!IsAllFilesExist(installPath))
List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT"); // {
foreach (string defaultPath in defaultPathList) // List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT");
{ // foreach (string defaultPath in defaultPathList)
if (IsAllFilesExist(defaultPath)) // {
{ // if (IsAllFilesExist(defaultPath))
return defaultPath; // {
} // return defaultPath;
} // }
} // }
else // }
{ // else
return installPath; // {
} // return installPath;
} // }
catch (Exception e) // }
{ // catch (Exception e)
Console.WriteLine(e.Message); // {
} // Console.WriteLine(e.Message);
// }
return null; //
// return null;
} }
/// <summary> /// <summary>

File diff suppressed because one or more lines are too long