From e9c6a493eb0932df3afc09fdb3dfba09206c10f1 Mon Sep 17 00:00:00 2001 From: "Namhyeon, Go" Date: Sat, 8 Mar 2025 22:52:45 +0900 Subject: [PATCH] Add the Monaco Editor to WelsonJS Launcher #137 --- .../WelsonJS.Launcher/MainForm.Designer.cs | 12 +- .../WelsonJS.Launcher/MainForm.cs | 19 ++++ WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs | 2 + .../WelsonJS.Launcher/ResourceServer.cs | 104 ++++++++++++++++++ .../WelsonJS.Launcher.csproj | 4 + .../WelsonJS.Launcher/editor.html | 26 +++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs create mode 100644 WelsonJS.Toolkit/WelsonJS.Launcher/editor.html diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.Designer.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.Designer.cs index b3ffa77..9358203 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.Designer.cs +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.Designer.cs @@ -41,6 +41,7 @@ this.instancesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.runAsAdministratorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.globalSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.startTheCodeEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); // @@ -133,7 +134,8 @@ this.userdefinedVariablesToolStripMenuItem, this.instancesToolStripMenuItem, this.runAsAdministratorToolStripMenuItem, - this.globalSettingsToolStripMenuItem}); + this.globalSettingsToolStripMenuItem, + this.startTheCodeEditorToolStripMenuItem}); this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; this.settingsToolStripMenuItem.Size = new System.Drawing.Size(62, 20); this.settingsToolStripMenuItem.Text = "Settings"; @@ -166,6 +168,13 @@ this.globalSettingsToolStripMenuItem.Text = "Global settings..."; this.globalSettingsToolStripMenuItem.Click += new System.EventHandler(this.globalSettingsToolStripMenuItem_Click); // + // startTheCodeEditorToolStripMenuItem + // + this.startTheCodeEditorToolStripMenuItem.Name = "startTheCodeEditorToolStripMenuItem"; + this.startTheCodeEditorToolStripMenuItem.Size = new System.Drawing.Size(196, 22); + this.startTheCodeEditorToolStripMenuItem.Text = "Start the code editor..."; + this.startTheCodeEditorToolStripMenuItem.Click += new System.EventHandler(this.startTheCodeEditorToolStripMenuItem_Click); + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); @@ -207,6 +216,7 @@ private System.Windows.Forms.ToolStripMenuItem instancesToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem runAsAdministratorToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem globalSettingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem startTheCodeEditorToolStripMenuItem; } } diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.cs index 1624c13..12ef8d8 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.cs +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/MainForm.cs @@ -210,5 +210,24 @@ namespace WelsonJS.Launcher { (new GlobalSettingsForm()).Show(); } + + private void startTheCodeEditorToolStripMenuItem_Click(object sender, EventArgs e) + { + if (Program.resourceServer == null) + { + Program.resourceServer = new ResourceServer("http://localhost:3000/", "editor.html"); + } + + if (!Program.resourceServer.IsRunning()) + { + Program.resourceServer.Start(); + ((ToolStripMenuItem)sender).Text = "Stop the code editor..."; + } + else + { + Program.resourceServer.Stop(); + ((ToolStripMenuItem)sender).Text = "Start the code editor..."; + } + } } } diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs index 5c20b80..6660b72 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs @@ -8,6 +8,8 @@ namespace WelsonJS.Launcher { internal static class Program { + public static ResourceServer resourceServer; + [STAThread] static void Main() { diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs new file mode 100644 index 0000000..290a17f --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs @@ -0,0 +1,104 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WelsonJS.Launcher +{ + public class ResourceServer + { + private readonly HttpListener _listener; + private CancellationTokenSource _cts; + private Task _serverTask; + private bool _isRunning; + private string _prefix; + private string _resourceName; + + public ResourceServer(string prefix, string resourceName) + { + _prefix = prefix; + _listener = new HttpListener(); + _listener.Prefixes.Add(prefix); + _resourceName = typeof(ResourceServer).Namespace + "." + resourceName; + } + + public void Start() + { + if (_isRunning) return; + + _isRunning = true; + _cts = new CancellationTokenSource(); + _listener.Start(); + + // Open the web browser + Process.Start(_prefix); + + // Run a task with cancellation token + _serverTask = Task.Run(() => ListenLoop(_cts.Token)); + } + + public void Stop() + { + _isRunning = false; + _cts.Cancel(); + _listener.Stop(); + + MessageBox.Show("Server stopped."); + } + + public bool IsRunning() + { + return _isRunning; + } + + private async Task ListenLoop(CancellationToken token) + { + while (!token.IsCancellationRequested && _isRunning) + { + try + { + ProcessRequest(await _listener.GetContextAsync()); + } + catch (Exception ex) + { + if (token.IsCancellationRequested || !_isRunning) break; + MessageBox.Show($"Error: {ex.Message}"); + } + } + } + + private void ProcessRequest(HttpListenerContext context) + { + string responseString = GetEmbeddedResource(); + + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + context.Response.ContentType = "text/html"; + context.Response.ContentLength64 = buffer.Length; + context.Response.OutputStream.Write(buffer, 0, buffer.Length); + context.Response.OutputStream.Close(); + } + + private string GetEmbeddedResource() + { + var assembly = Assembly.GetExecutingAssembly(); + using (Stream stream = assembly.GetManifestResourceStream(_resourceName)) + { + if (stream == null) + { + return "

Could not find the resource.

"; + } + + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + return reader.ReadToEnd(); + } + } + } + + } +} diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/WelsonJS.Launcher.csproj b/WelsonJS.Toolkit/WelsonJS.Launcher/WelsonJS.Launcher.csproj index 69fc774..756c646 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/WelsonJS.Launcher.csproj +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/WelsonJS.Launcher.csproj @@ -96,6 +96,7 @@ GlobalSettingsForm.cs + EnvForm.cs @@ -151,5 +152,8 @@ + + + \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/editor.html b/WelsonJS.Toolkit/WelsonJS.Launcher/editor.html new file mode 100644 index 0000000..f8866b9 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/editor.html @@ -0,0 +1,26 @@ + + + + + + + +

Monaco Editor Sync Loading Sample

+
+ + + + + + + + \ No newline at end of file