welsonjs/WelsonJS.Toolkit/WelsonJS.Launcher/Program.cs
Namhyeon, Go 130a6fd767 Add ChakraCore integration and native bootstrap logic
Introduces JsCore for ChakraCore P/Invoke, JsSerializer for JSON utilities via JS, and NativeBootstrap for robust native DLL loading. Updates Program.cs to initialize native dependencies at startup and registers new source files in the project file.
2025-09-26 17:04:14 +09:00

216 lines
6.9 KiB
C#

// Program.cs
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Configuration;
namespace WelsonJS.Launcher
{
internal static class Program
{
private const string _appDataSubDirectory = "WelsonJS";
private static readonly ICompatibleLogger _logger;
public static Mutex _mutex;
public static ResourceServer _resourceServer;
static Program()
{
// set up logger
_logger = new TraceLogger();
// load native libraries
NativeBootstrap.Init(new string[] {
"ChakraCore.dll"
}, _appDataSubDirectory, _logger);
}
[STAThread]
static void Main()
{
// create the mutex
_mutex = new Mutex(true, "WelsonJS.Launcher", out bool createdNew);
if (!createdNew)
{
_logger.Info("WelsonJS Launcher already running.");
return;
}
// draw the main form
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm(_logger));
// destory the mutex
try {
_mutex.ReleaseMutex();
} catch { /* ignore if not owned */ }
_mutex.Dispose();
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceAapplication = false)
{
if (!isConsoleApplication)
{
if (!File.Exists(Path.Combine(workingDirectory, entryFileName)))
{
throw new Exception("Not Found: " + entryFileName);
}
}
else
{
if (!Directory.EnumerateFiles(workingDirectory, scriptName + ".*").Any())
{
throw new Exception("Not found matches file: " + scriptName);
}
}
Process process = new Process
{
StartInfo = new ProcessStartInfo("cmd")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
Arguments = "/k",
}
};
process.Start();
process.StandardInput.WriteLine("pushd " + workingDirectory);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
if (isInteractiveServiceAapplication)
{
process.StandardInput.WriteLine($"start cmd /c startInteractiveService.bat");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
else if (!isConsoleApplication)
{
process.StandardInput.WriteLine(entryFileName);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
else
{
process.StandardInput.WriteLine($"start cmd /c cscript app.js {scriptName}");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
}
process.StandardInput.Close();
process.WaitForExit();
}
public static string GetFinalDirectory(string path)
{
string[] directories = Directory.GetDirectories(path);
while (directories.Length == 1)
{
path = directories[0];
directories = Directory.GetDirectories(path);
}
return path;
}
public static string GetAppDataPath()
{
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"WelsonJS"
);
Directory.CreateDirectory(path);
if (!Directory.Exists(path))
{
throw new IOException("Failed to create directory: " + path);
}
return path;
}
public static string GetWorkingDirectory(string instanceId, bool followSubDirectory = false)
{
string workingDirectory = Path.Combine(GetAppDataPath(), instanceId);
if (followSubDirectory)
{
if (!Directory.Exists(workingDirectory))
{
workingDirectory = Path.Combine(Path.GetTempPath(), instanceId);
}
workingDirectory = GetFinalDirectory(workingDirectory);
}
return workingDirectory;
}
public static void InitializeResourceServer()
{
lock(typeof(Program))
{
if (_resourceServer == null)
{
_resourceServer = new ResourceServer(GetAppConfig("ResourceServerPrefix"), "editor.html", _logger);
}
}
}
public static void OpenWebBrowser(string url)
{
Uri resourceServerUri = new Uri(GetAppConfig("ResourceServerPrefix"));
Uri devToolsUri = new Uri(GetAppConfig("ChromiumDevToolsPrefix"));
string userDataDir = Path.Combine(GetAppDataPath(), "EdgeUserProfile");
string remoteAllowOrigins = $"{resourceServerUri.Scheme}://{resourceServerUri.Host}:{resourceServerUri.Port}";
int remoteDebuggingPort = devToolsUri.Port;
string[] arguments = {
$"\"{url}\"",
$"--remote-debugging-port={remoteDebuggingPort}",
$"--remote-allow-origins={remoteAllowOrigins}", // for security reason
$"--user-data-dir=\"{userDataDir}\""
};
Process.Start(new ProcessStartInfo
{
FileName = Program.GetAppConfig("ChromiumFileName"),
Arguments = string.Join(" ", arguments),
UseShellExecute = true
});
}
public static string GetAppConfig(string key)
{
string value = ConfigurationManager.AppSettings[key];
if (!string.IsNullOrEmpty(value))
{
return value;
}
value = Properties.Resources.ResourceManager.GetString(key);
if (!string.IsNullOrEmpty(value))
{
return value;
}
return null;
}
}
}