111 lines
5.2 KiB
C#
111 lines
5.2 KiB
C#
using System;
|
||||
|
|
using System.Drawing;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Windows.Forms;
|
|||
|
|
|
|||
|
|
// 入口。正常双击 => 打开界面;带 /dryrun => 只做路径自检并把结果写进 launcher.log,不弹界面、不启动任何进程。
|
|||
|
|
internal static class Program
|
|||
|
|
{
|
|||
|
|
[STAThread]
|
|||
|
|
private static int Main(string[] args)
|
|||
|
|
{
|
|||
|
|
foreach (var a in args)
|
|||
|
|
{
|
|||
|
|
var t = (a ?? "").Trim().ToLowerInvariant();
|
|||
|
|
if (t == "/dryrun" || t == "--dryrun" || t == "-dryrun") return DryRun();
|
|||
|
|
if (t == "/uitest" || t == "--uitest" || t == "-uitest") return UiTest(args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Application.EnableVisualStyles();
|
|||
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
|||
|
|
Application.Run(new MainForm());
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 界面冒烟测试:真的把 MainForm 造出来、Show 出来、跑几轮消息循环,
|
|||
|
|
// 再把客户区 DrawToBitmap 存成 uitest.png。用来在没法肉眼看界面的环境里
|
|||
|
|
// 既能证明「构造 + 布局 + 定时器」不炸,又能真的看到界面长什么样。
|
|||
|
|
private static int UiTest(string[] args)
|
|||
|
|
{
|
|||
|
|
// --uitest-stop:拍完自然态后,再强制把服务端按键推成「关闭服务端」态拍第二张。
|
|||
|
|
// 服务端当前没跑时,光靠 --uitest 是看不到「关闭服务端」外观的(红色停止图标)。
|
|||
|
|
bool wantStop = false;
|
|||
|
|
foreach (var a in args)
|
|||
|
|
{
|
|||
|
|
var t = (a ?? "").Trim().ToLowerInvariant();
|
|||
|
|
if (t == "--uitest-stop" || t == "-uitest-stop") wantStop = true;
|
|||
|
|
}
|
|||
|
|
string root = AppContext.BaseDirectory.TrimEnd('\\', '/');
|
|||
|
|
string log = Path.Combine(root, "tools", "launcher", "launcher.log");
|
|||
|
|
void L(string s)
|
|||
|
|
{
|
|||
|
|
try { File.AppendAllText(log, DateTime.Now.ToString("HH:mm:ss") + " " + s + Environment.NewLine); } catch { }
|
|||
|
|
}
|
|||
|
|
string png = Path.Combine(root, "uitest.png");
|
|||
|
|
static void Snap(Form f, string path)
|
|||
|
|
{
|
|||
|
|
using var bmp = new Bitmap(f.ClientSize.Width, f.ClientSize.Height);
|
|||
|
|
f.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
|
|||
|
|
bmp.Save(path, System.Drawing.Imaging.ImageFormat.Png);
|
|||
|
|
}
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
Application.EnableVisualStyles();
|
|||
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
|||
|
|
using var f = new MainForm();
|
|||
|
|
f.Opacity = 1;
|
|||
|
|
L("[UITEST] 1 构造完成");
|
|||
|
|
// ⛑ 必须真的 Show 一次,否则子控件不会 Realize,DrawToBitmap 只拍得到窗体自绘层。
|
|||
|
|
// 挪到屏幕外,避免在用户桌面上闪一下。
|
|||
|
|
f.StartPosition = FormStartPosition.Manual;
|
|||
|
|
f.Location = new Point(-4000, -4000);
|
|||
|
|
f.Show();
|
|||
|
|
for (int i = 0; i < 10; i++) { Application.DoEvents(); System.Threading.Thread.Sleep(20); }
|
|||
|
|
f.PerformLayout();
|
|||
|
|
L("[UITEST] 2 已显示,Size=" + f.ClientSize.Width + "x" + f.ClientSize.Height);
|
|||
|
|
Application.DoEvents();
|
|||
|
|
Snap(f, png);
|
|||
|
|
if (wantStop)
|
|||
|
|
{
|
|||
|
|
// ⛑ 强推状态后「立刻」拍,中间不能 DoEvents —— 否则 1 秒轮询会把按键改回自然态
|
|||
|
|
f.ForceServerButtonForTest(true);
|
|||
|
|
string png2 = Path.Combine(root, "uitest-stop.png");
|
|||
|
|
Snap(f, png2);
|
|||
|
|
L("[UITEST] 已强制「关闭服务端」态,截图 = " + png2);
|
|||
|
|
}
|
|||
|
|
f.Close();
|
|||
|
|
L("[UITEST] 界面构造 + 布局 + 轮询 OK,截图 = " + png);
|
|||
|
|
return 0; }
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
L("[UITEST] 异常: " + ex);
|
|||
|
|
return 3;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static int DryRun()
|
|||
|
|
{
|
|||
|
|
string root = AppContext.BaseDirectory.TrimEnd('\\', '/');
|
|||
|
|
string log = Path.Combine(root, "tools", "launcher", "launcher.log");
|
|||
|
|
void L(string s)
|
|||
|
|
{
|
|||
|
|
try { File.AppendAllText(log, DateTime.Now.ToString("HH:mm:ss") + " " + s + Environment.NewLine); } catch { }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
L("============ DRYRUN(界面版) ============");
|
|||
|
|
L("root = " + root);
|
|||
|
|
string startCmd = Path.Combine(root, "START.cmd");
|
|||
|
|
string injector = Path.Combine(root, "tools", "AnantaInjector", "unified_loader.py");
|
|||
|
|
// ⛑ 优先随包分发的便携 python;没有再退回开发者本机的环境(避免分发给别人时报「找不到」)。
|
|||
|
|
string python = Path.Combine(root, "tools", "python", "python.exe");
|
|||
|
|
if (!File.Exists(python)) python = @"C:\Users\Noiro\.workbuddy\binaries\python\envs\default\Scripts\python.exe";
|
|||
|
|
string serverCfg = Path.Combine(root, "config", "private-server.json");
|
|||
|
|
|
|||
|
|
L("START.cmd = " + startCmd + " exists=" + File.Exists(startCmd));
|
|||
|
|
L("injector = " + injector + " exists=" + File.Exists(injector));
|
|||
|
|
L("python = " + python + " exists=" + File.Exists(python));
|
|||
|
|
L("serverCfg = " + serverCfg + " exists=" + File.Exists(serverCfg));
|
|||
|
|
L("[DRYRUN] 路径自检完成,未启动任何进程。");
|
|||
|
|
return File.Exists(startCmd) && File.Exists(injector) && File.Exists(python) ? 0 : 2;
|
|||
|
|
}
|
|||
|
|
}
|