From 598b397441da6e6749a8aac625ebf67b6b412fbe Mon Sep 17 00:00:00 2001 From: hbl917070 Date: Tue, 19 Mar 2024 01:56:42 +0800 Subject: [PATCH] Add feature to close all Tiefsee --- .gitignore | 1 + BuildAll/BuildAll.csproj | 9 +- Tiefsee/Program.cs | 8 +- Tiefsee/QuickRun.cs | 131 +++++++++++++++----------- Tiefsee/Server/WebServerController.cs | 11 +++ Tiefsee/StartWindow.cs | 28 +++++- Tiefsee/VW/WV_Window.cs | 8 +- Tiefsee/WebWindow.cs | 20 ++++ TiefseeLauncherDll/Program.cs | 55 ++++++++--- Www/ts/SettingWindow/SettingWindow.ts | 2 +- Www/ts/d/NetAPI.d.ts | 4 +- 11 files changed, 188 insertions(+), 89 deletions(-) diff --git a/.gitignore b/.gitignore index 3832907..66e1e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ TiefseeLauncher/x64 TiefseeLauncher/Resource.aps +TiefseeLauncher/Release diff --git a/BuildAll/BuildAll.csproj b/BuildAll/BuildAll.csproj index 9b3fed1..821768d 100644 --- a/BuildAll/BuildAll.csproj +++ b/BuildAll/BuildAll.csproj @@ -24,8 +24,8 @@ - - + + @@ -40,11 +40,6 @@ - - - - - diff --git a/Tiefsee/Program.cs b/Tiefsee/Program.cs index a45afc0..be6304f 100644 --- a/Tiefsee/Program.cs +++ b/Tiefsee/Program.cs @@ -43,13 +43,19 @@ static void Main(string[] args) { var args2 = AppInstance.GetActivatedEventArgs(); if (args2 != null) { if (args2.Kind == ActivationKind.StartupTask) { - args = new string[] { "none" }; + args = ["none"]; } } } catch { } } + // 啟動參數是 closeAll + if (args.Length == 1 && args[0] == "closeAll") { + QuickRun.CloseAllWindow(); + return; + } + bool argsIsNone = (args.Length == 1 && args[0] == "none"); // 啟動參數是 none if (args.Length >= 1 && args[0] == "restart") { // 啟動參數是 restart diff --git a/Tiefsee/QuickRun.cs b/Tiefsee/QuickRun.cs index 6d2489c..11fead6 100644 --- a/Tiefsee/QuickRun.cs +++ b/Tiefsee/QuickRun.cs @@ -1,6 +1,6 @@ -using System.IO; +using System.Diagnostics; +using System.IO; using System.Net.Http; -using System.Text; namespace Tiefsee; @@ -33,14 +33,73 @@ public static void WindowFreed() { /// public static bool Check(string[] args) { - if (Program.startType == 1) { // 直接啟動 + // 直接啟動 + if (Program.startType == 1) { return false; } + // 找不到記錄 port 的資料夾 if (Directory.Exists(AppPath.appDataPort) == false) { return false; } + int port = GetPort(); + + // 沒有可以正常請求的 port + if (port == -1) { + return false; + } + + NewWindow(args, port); + return true; + } + + /// + /// 結束程式 + /// + public static void Exit() { + runNumber = 0; + WindowFreed(); + } + + /// + /// 關閉全部的視窗 + /// + public static void CloseAllWindow() { + + // 如果是 直接啟動,直接強制結束所有 process + if (Program.startType == 1) { + Process[] proc = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName); + for (int i = proc.Length - 1; i >= 0; i--) { + try { + if (proc[i].Id == Process.GetCurrentProcess().Id) + continue; + proc[i].Kill(); // 關閉執行中的程式 + } + catch { } + } + + // 刪除所有的 port 檔案 + foreach (string filePort in Directory.GetFiles(AppPath.appDataPort, "*")) { + try { + File.Delete(filePort); + continue; + } + catch { } + } + return; + } + + int port = GetPort(); + string uri = $"http://127.0.0.1:{port}/api/closeAllWindow"; + SendRequest(uri); + } + + /// + /// + /// + private static int GetPort() { + foreach (string filePort in Directory.GetFiles(AppPath.appDataPort, "*")) { // 判斷目前已經開啟的視窗 try { @@ -56,77 +115,35 @@ public static bool Check(string[] args) { string port = Path.GetFileName(filePort); // 偵測是否可用 string uri = $"http://127.0.0.1:{port}/api/check"; - using (HttpClient client = new HttpClient()) { - client.Timeout = TimeSpan.FromSeconds(5); // 逾時 - client.DefaultRequestHeaders.Add("User-Agent", Program.webvviewUserAgent); - - HttpResponseMessage response = client.GetAsync(uri).Result; - } - - if (Program.startType == 2) { // 快速啟動 - NewWindow(args, port); - return true; - } + SendRequest(uri); - if (Program.startType == 3) { // 快速啟動且常駐 - NewWindow(args, port); - return true; - } - - if (Program.startType == 4) { // 單一執行個體 - NewWindow(args, port); - return true; - } - - if (Program.startType == 5) { // 單一執行個體且常駐 - NewWindow(args, port); - return true; - } + return Int32.Parse(port); } catch { } File.Delete(filePort); // 如果這個 port 超過時間沒有回應,就當做無法使用,將檔案刪除 - } - - return false; + return -1; } /// - /// 關閉全部的視窗 (結束程式) + /// /// - public static void CloseAllWindow() { - runNumber = 0; - WindowFreed(); + private static void NewWindow(string[] args, int port) { + string base64 = Uri.EscapeDataString(string.Join("\n", args)); + string uri = $"http://127.0.0.1:{port}/api/newWindow?path=" + base64; + SendRequest(uri); } /// - /// + /// 發送 http 請求 /// - /// - /// - private static void NewWindow(string[] args, string port) { - - // 啟動參數 - StringBuilder sb = new(); - for (int i = 0; i < args.Length; i++) { - if (i != args.Length - 1) { - sb.Append(args[i] + "\n"); - } - else { - sb.Append(args[i]); - } - } - - // 開啟新視窗 - string base64 = Uri.EscapeDataString(sb.ToString()); - string uri = $"http://127.0.0.1:{port}/api/newWindow?path=" + base64; - - using (HttpClient client = new HttpClient()) { + private static Task SendRequest(string uri) { + using (HttpClient client = new()) { client.Timeout = TimeSpan.FromSeconds(5); // 逾時 client.DefaultRequestHeaders.Add("User-Agent", Program.webvviewUserAgent); HttpResponseMessage response = client.GetAsync(uri).Result; - // string responseContent = response.Content.ReadAsStringAsync().Result; + return response.Content.ReadAsStringAsync(); } } diff --git a/Tiefsee/Server/WebServerController.cs b/Tiefsee/Server/WebServerController.cs index 294123a..7a23172 100644 --- a/Tiefsee/Server/WebServerController.cs +++ b/Tiefsee/Server/WebServerController.cs @@ -21,6 +21,7 @@ public WebServerController(WebServer ws) { webServer.RouteAdd("/api/check", Ckeck); webServer.RouteAdd("/api/newWindow", NewWindow); + webServer.RouteAdd("/api/closeAllWindow", CloseAllWindow); webServer.RouteAdd("/api/getExif", GetExif); webServer.RouteAdd("/api/getPdf", GetPdf); @@ -293,6 +294,16 @@ private void NewWindow(RequestData d) { WriteString(d, "ok"); } + /// + /// 關閉全部的視窗 + /// + private void CloseAllWindow(RequestData d) { + Adapter.UIThread(() => { + WebWindow.CloseAllWindow(); + }); + WriteString(d, "ok"); + } + /// /// /// diff --git a/Tiefsee/StartWindow.cs b/Tiefsee/StartWindow.cs index 74f75e5..f87e671 100644 --- a/Tiefsee/StartWindow.cs +++ b/Tiefsee/StartWindow.cs @@ -1,6 +1,7 @@ using Microsoft.Web.WebView2.Core; using System.IO; using System.Windows.Input; +using Windows.UI.StartScreen; namespace Tiefsee; @@ -27,8 +28,9 @@ public StartWindow() { Adapter.Initialize(); Plugin.Init(); - PortLock(); // 寫入檔案,表示此port已經被佔用 - CheckWebView2(); // 檢查是否有webview2執行環境 + PortLock(); // 寫入檔案,表示此 port 已經被佔用 + CheckWebView2(); // 檢查是否有 webview2 執行環境 + InitJumpTask(); // 初始化 JumpTask //-------------- @@ -209,6 +211,28 @@ public void RunNotifyIcon() { nIcon.ContextMenuStrip = cm; } + /// + /// + /// + public async void InitJumpTask() { + + // 獲取默認的 JumpList + var jumpList = await Windows.UI.StartScreen.JumpList.LoadCurrentAsync(); + + // 清除默認的 JumpList + jumpList.Items.Clear(); + + if (Program.startType != 4 && Program.startType != 5) { + var item = JumpListItem.CreateWithArguments("closeAll", "Close all Tiefsee"); + // item.Description = "Close all Tiefsee"; + // item.Logo = new Uri("ms-appx:///t1.ico"); + jumpList.Items.Add(item); + } + + // 保存 JumpList + await jumpList.SaveAsync(); + } + /// /// 初始化webview2 /// diff --git a/Tiefsee/VW/WV_Window.cs b/Tiefsee/VW/WV_Window.cs index 39dc69b..6203a97 100644 --- a/Tiefsee/VW/WV_Window.cs +++ b/Tiefsee/VW/WV_Window.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -66,10 +66,10 @@ public WebWindow NewSubWindow(string url, object[] args) { } /// - /// 關閉全部的視窗 (結束程式) + /// 關閉全部的視窗 /// - public void CloseAllWindow() { - QuickRun.CloseAllWindow(); + public void Exit() { + QuickRun.Exit(); } /// diff --git a/Tiefsee/WebWindow.cs b/Tiefsee/WebWindow.cs index 346a3dc..409da55 100644 --- a/Tiefsee/WebWindow.cs +++ b/Tiefsee/WebWindow.cs @@ -17,6 +17,8 @@ public class WebWindow : FormNone { private bool isShow = false; // 是否已經顯式過視窗(用於單一啟動 public bool isDelayInit = false; // 是否延遲初始化(暫存視窗必須設定成true + public static List webWindowList = new(); // 用於記錄所有視窗 + // 用於記錄全螢幕前的狀態 private FormWindowState tempFormWindowState = FormWindowState.Normal; private bool tempFullScreen = false; @@ -33,6 +35,11 @@ public class WebWindow : FormNone { /// /// public WebWindow() { + webWindowList.Add(this); + + this.FormClosed += (sender, e) => { + webWindowList.Remove(this); + }; } /// @@ -193,6 +200,19 @@ private static string GetHtmlFilePath(string fileName) { return p; } + /// + /// 關閉所有視窗 + /// + public static void CloseAllWindow() { + int count = webWindowList.Count; + // 從後往前關閉,避免關閉後,webWindowList 的數量減少 + for (int i = count - 1; i >= 0; i--) { + var item = webWindowList[i]; + if (item == null || item.IsDisposed || item == tempWindow) { continue; } + webWindowList[i].Close(); + } + } + /// /// 觸發 js 的 baseWindow.onCreate /// diff --git a/TiefseeLauncherDll/Program.cs b/TiefseeLauncherDll/Program.cs index 3feee75..a97980c 100644 --- a/TiefseeLauncherDll/Program.cs +++ b/TiefseeLauncherDll/Program.cs @@ -64,19 +64,25 @@ public void Init(string[] args) { appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Tiefsee"); } + // 啟動參數是 closeAll + if (args.Length == 1 && args[0] == "closeAll") { + RunTiefseeCore(args); + return; + } + appDataStartIni = Path.Combine(appData, "Start.ini"); appDataPort = Path.Combine(appData, "Port"); var iniManager = new IniManager(appDataStartIni); startType = Int32.Parse(iniManager.ReadIniFile("setting", "startType", "3")); if (startType == 1) { - RunTiefseeCore(args); // 啟動 TiefseeCore.exe + RunTiefseeCore(args); } else { // 如果允許快速啟動,就不開啟新個體 if (Check(args)) { return; } - RunTiefseeCore(args); // 啟動 TiefseeCore.exe + RunTiefseeCore(args); } } @@ -95,10 +101,27 @@ private void RunTiefseeCore(string[] args) { /// private bool Check(string[] args) { + // 找不到記錄 port 的資料夾 if (Directory.Exists(appDataPort) == false) { return false; } + int port = GetPort(); + + // 沒有可以正常請求的 port + if (port == -1) { + return false; + } + + NewWindow(args, port); + return true; + } + + /// + /// + /// + private int GetPort() { + foreach (string filePort in Directory.GetFiles(appDataPort, "*")) { // 判斷目前已經開啟的視窗 try { @@ -114,33 +137,35 @@ private bool Check(string[] args) { string port = Path.GetFileName(filePort); // 偵測是否可用 string uri = $"http://127.0.0.1:{port}/api/check"; - using (HttpClient client = new HttpClient()) { - client.Timeout = TimeSpan.FromSeconds(5); // 逾時 - client.DefaultRequestHeaders.Add("User-Agent", webvviewUserAgent); - using HttpResponseMessage response = client.GetAsync(uri).Result; - } - - NewWindow(args, port); - return true; + SendRequest(uri); + + return Int32.Parse(port); } catch { } File.Delete(filePort); // 如果這個 port 超過時間沒有回應,就當做無法使用,將檔案刪除 } - return false; + return -1; } /// /// 開啟新視窗 /// - private void NewWindow(string[] args, string port) { + private void NewWindow(string[] args, int port) { string base64 = Uri.EscapeDataString(string.Join("\n", args)); string uri = $"http://127.0.0.1:{port}/api/newWindow?path=" + base64; - using (HttpClient client = new HttpClient()) { + SendRequest(uri); + } + + /// + /// 發送 http 請求 + /// + private Task SendRequest(string uri) { + using (HttpClient client = new()) { client.Timeout = TimeSpan.FromSeconds(5); // 逾時 client.DefaultRequestHeaders.Add("User-Agent", webvviewUserAgent); - using HttpResponseMessage response = client.GetAsync(uri).Result; - // string responseContent = response.Content.ReadAsStringAsync().Result; + HttpResponseMessage response = client.GetAsync(uri).Result; + return response.Content.ReadAsStringAsync(); } } diff --git a/Www/ts/SettingWindow/SettingWindow.ts b/Www/ts/SettingWindow/SettingWindow.ts index 37aa142..8736588 100644 --- a/Www/ts/SettingWindow/SettingWindow.ts +++ b/Www/ts/SettingWindow/SettingWindow.ts @@ -1440,7 +1440,7 @@ class SettingWindow { imgPath = `"${imgPath}"`; let exePath = await WV_Window.GetAppPath(); WV_RunApp.ProcessStart(exePath, imgPath, true, false); - WV_Window.CloseAllWindow(); + WV_Window.Exit(); } } diff --git a/Www/ts/d/NetAPI.d.ts b/Www/ts/d/NetAPI.d.ts index 93af792..6a0eb3c 100644 --- a/Www/ts/d/NetAPI.d.ts +++ b/Www/ts/d/NetAPI.d.ts @@ -73,8 +73,8 @@ interface WV_Window { */ NewSubWindow(url: string, args: string[]): WebWindow; - /** 關閉全部的視窗(結束程式) */ - CloseAllWindow(); + /** 結束程式 */ + Exit(); /** 傳入 webWindow,將其設為目前視窗的子視窗*/ SetOwner(webwindow: WebWindow);