Merge pull request #343 from gnh1201/dev
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
Deploy Jekyll with GitHub Pages dependencies preinstalled / build (push) Waiting to run
Deploy Jekyll with GitHub Pages dependencies preinstalled / deploy (push) Blocked by required conditions

Support the file association registration for WelsonJS supported file types
This commit is contained in:
Namhyeon Go 2025-11-20 17:32:57 +09:00 committed by GitHub
commit 2317be5c49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 889 additions and 85 deletions

1
.gitignore vendored
View File

@ -551,3 +551,4 @@ settings.ini
defaultService.js
lib/*.private.js
data/python313.zip
do_not_push_production_on_friday.js

View File

@ -156,7 +156,7 @@ namespace WelsonJS.Launcher
ZipFile.ExtractToDirectory(filePath, _workingDirectory);
// record the first deploy time
RecordFirstDeployTime(_workingDirectory, _instanceId);
Program.RecordFirstDeployTime(_workingDirectory, _instanceId);
// follow the sub-directory
_workingDirectory = Program.GetWorkingDirectory(_instanceId, true);
@ -194,41 +194,6 @@ namespace WelsonJS.Launcher
return Program._resourceServer.IsRunning();
}
private void RecordFirstDeployTime(string directory, string instanceId)
{
// get current time
DateTime now = DateTime.Now;
// record to the metadata database
InstancesForm instancesForm = new InstancesForm();
try
{
instancesForm.GetDatabaseInstance().Insert(new Dictionary<string, object>
{
["InstanceId"] = instanceId,
["FirstDeployTime"] = now
}, out _);
}
catch (Exception ex)
{
_logger.Error($"Failed to record first deploy time: {ex.Message}");
}
instancesForm.Dispose();
// record to the instance directory
try
{
string filePath = Path.Combine(directory, ".welsonjs_first_deploy_time");
string text = now.ToString(_dateTimeFormat);
File.WriteAllText(filePath, text);
}
catch (Exception ex)
{
_logger.Error($"Failed to record first deploy time: {ex.Message}");
}
}
private bool IsInAdministrator()
{
try

View File

@ -4,12 +4,13 @@
// https://github.com/gnh1201/welsonjs
//
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Configuration;
namespace WelsonJS.Launcher
{
@ -19,9 +20,13 @@ namespace WelsonJS.Launcher
public static Mutex _mutex;
public static ResourceServer _resourceServer;
public static string _dateTimeFormat;
static Program()
{
// get the date time format
_dateTimeFormat = GetAppConfig("DateTimeFormat");
// set up logger
_logger = new TraceLogger();
@ -41,8 +46,22 @@ namespace WelsonJS.Launcher
}
[STAThread]
static void Main()
static void Main(string[] args)
{
// if set the target file path
string targetFilePath = GetTargetFilePath(args);
if (!string.IsNullOrEmpty(targetFilePath))
{
try {
HandleTargetFilePath(targetFilePath);
}
catch (Exception e)
{
_logger.Error($"Initialization failed: {e}");
}
return;
}
// create the mutex
_mutex = new Mutex(true, "WelsonJS.Launcher", out bool createdNew);
if (!createdNew)
@ -56,14 +75,203 @@ namespace WelsonJS.Launcher
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm(_logger));
// destory the mutex
try {
// release the mutex
try
{
_mutex.ReleaseMutex();
} catch { /* ignore if not owned */ }
}
catch { /* ignore if not owned */ }
_mutex.Dispose();
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceAapplication = false)
public static void RecordFirstDeployTime(string directory, string instanceId)
{
// get current time
DateTime now = DateTime.Now;
// record to the metadata database
using (InstancesForm instancesForm = new InstancesForm())
{
try
{
instancesForm.GetDatabaseInstance().Insert(new Dictionary<string, object>
{
["InstanceId"] = instanceId,
["FirstDeployTime"] = now
}, out _);
}
catch (Exception ex)
{
_logger.Error($"Failed to record first deploy time: {ex.Message}");
}
}
// record to the instance directory
try
{
string filePath = Path.Combine(directory, ".welsonjs_first_deploy_time");
string text = now.ToString(_dateTimeFormat);
File.WriteAllText(filePath, text);
}
catch (Exception ex)
{
_logger.Error($"Failed to record first deploy time: {ex.Message}");
}
}
private static string GetTargetFilePath(string[] args)
{
if (args == null || args.Length == 0) return null;
for (int i = 0; i < args.Length; i++)
{
string token = args[i];
if (string.Equals(token, "--file", StringComparison.OrdinalIgnoreCase) ||
string.Equals(token, "/file", StringComparison.OrdinalIgnoreCase))
{
if (i + 1 < args.Length)
{
return args[i + 1];
}
}
if (token.StartsWith("--file=", StringComparison.OrdinalIgnoreCase))
{
return token.Substring("--file=".Length).Trim('"');
}
}
return null;
}
private static void HandleTargetFilePath(string filePath)
{
string fileExtension = Path.GetExtension(filePath);
if (String.IsNullOrEmpty(fileExtension))
{
throw new ArgumentException("The file extension is null or empty");
}
if (fileExtension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
{
throw new NotImplementedException("Not implemented yet.");
}
if (fileExtension.Equals(".js", StringComparison.OrdinalIgnoreCase))
{
string instanceId = Guid.NewGuid().ToString();
string workingDirectory = CreateInstanceDirectory(instanceId);
string appRoot = GetAppRootDirectory();
string appBaseSource = Path.Combine(appRoot, "app.js");
if (!File.Exists(appBaseSource))
{
throw new FileNotFoundException("app.js not found in application root.", appBaseSource);
}
string appBaseDestination = Path.Combine(workingDirectory, "app.js");
File.Copy(appBaseSource, appBaseDestination, overwrite: true);
string assetsSource = Path.Combine(appRoot, "app", "assets", "js");
string assetsDestination = Path.Combine(workingDirectory, "app", "assets", "js");
CopyDirectoryRecursive(assetsSource, assetsDestination);
string libSource = Path.Combine(appRoot, "lib");
string libDestination = Path.Combine(workingDirectory, "lib");
CopyDirectoryRecursive(libSource, libDestination);
string entrypointDestination = Path.Combine(workingDirectory, "bootstrap.js");
File.Copy(filePath, entrypointDestination, overwrite: true);
RecordFirstDeployTime(workingDirectory, instanceId);
RunCommandPrompt(
workingDirectory: workingDirectory,
entryFileName: "app.js",
scriptName: "bootstrap",
isConsoleApplication: true,
isInteractiveServiceApplication: false
);
return;
}
throw new NotSupportedException($"Unsupported file type: {fileExtension}");
}
private static string GetAppRootDirectory()
{
string[] candidates = new[]
{
GetAppConfig("AppRootDirectory"),
AppDomain.CurrentDomain.BaseDirectory,
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "WelsonJS"),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WelsonJS"),
};
foreach (string dir in candidates)
{
if (string.IsNullOrEmpty(dir))
continue;
string appJs = Path.Combine(dir, "app.js");
if (File.Exists(appJs))
return dir;
}
throw new FileNotFoundException("Could not locate app.js in any known application root directory.");
}
private static string CreateInstanceDirectory(string instanceId)
{
string workingDirectory = GetWorkingDirectory(instanceId);
try
{
// check if the working directory exists
if (Directory.Exists(workingDirectory))
{
throw new InvalidOperationException("GUID validation failed. Directory already exists.");
}
Directory.CreateDirectory(workingDirectory);
}
catch
{
throw new Exception("Instance Initialization failed");
}
return workingDirectory;
}
private static void CopyDirectoryRecursive(string sourceDir, string destDir)
{
if (!Directory.Exists(sourceDir))
{
throw new DirectoryNotFoundException("Source directory not found: " + sourceDir);
}
Directory.CreateDirectory(destDir);
foreach (var file in Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories))
{
string normalizedSource = sourceDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
string relativePath = file.Substring(normalizedSource.Length + 1).TrimStart(
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar
);
string targetPath = Path.Combine(destDir, relativePath);
string targetDir = Path.GetDirectoryName(targetPath);
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
File.Copy(file, targetPath, overwrite: true);
}
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceApplication = false)
{
if (!isConsoleApplication)
{
@ -93,33 +301,37 @@ namespace WelsonJS.Launcher
};
process.Start();
process.StandardInput.WriteLine("pushd " + workingDirectory);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
StreamWriter input = process.StandardInput;
StreamReader output = process.StandardOutput;
if (isInteractiveServiceAapplication)
input.WriteLine("pushd " + workingDirectory);
input.WriteLine();
input.Flush();
output.ReadLine();
if (isInteractiveServiceApplication)
{
process.StandardInput.WriteLine($"start cmd /c startInteractiveService.bat");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
input.WriteLine($"start cmd /c startInteractiveService.bat");
input.WriteLine();
input.Flush();
output.ReadLine();
}
else if (!isConsoleApplication)
{
process.StandardInput.WriteLine(entryFileName);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
input.WriteLine(entryFileName);
input.WriteLine();
input.Flush();
output.ReadLine();
}
else
{
process.StandardInput.WriteLine($"start cmd /c cscript app.js {scriptName}");
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
input.WriteLine($"start cmd /c cscript app.js {scriptName}");
input.WriteLine();
input.Flush();
output.ReadLine();
}
process.StandardInput.Close();
input.Close();
process.WaitForExit();
}

298
afterInstall.ps1 Normal file
View File

@ -0,0 +1,298 @@
# ================================
# CONFIGURATION
# ================================
$AppName = "welsonjs"
$TargetDir = Join-Path $env:APPDATA $AppName
$TmpDir = Join-Path $env:TEMP "$AppName-downloads"
Write-Host ""
Write-Host "[*] Target directory : $TargetDir"
Write-Host "[*] Temporary directory: $TmpDir"
Write-Host ""
# Ensure base directories exist
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
New-Item -ItemType Directory -Path $TmpDir -Force | Out-Null
# ================================
# ARCHITECTURE DETECTION
# ================================
$arch = "x86"
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { $arch = "x64" }
elseif ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { $arch = "arm64" }
if ($env:PROCESSOR_ARCHITEW6432 -eq "AMD64") { $arch = "x64" }
elseif ($env:PROCESSOR_ARCHITEW6432 -eq "ARM64") { $arch = "arm64" }
Write-Host "[*] Detected architecture: $arch"
Write-Host ""
# ================================
# HELPER FUNCTIONS
# ================================
function Ensure-EmptyDirectory {
param(
[Parameter(Mandatory=$true)]
[string]$Path
)
# If a file exists at the path, remove it
if (Test-Path $Path -PathType Leaf) {
Write-Host "[WARN] A file exists at path '$Path'. Deleting it..."
Remove-Item -Path $Path -Force
}
# Ensure directory exists
if (-not (Test-Path $Path -PathType Container)) {
Write-Host "[*] Creating directory: $Path"
New-Item -ItemType Directory -Path $Path -Force | Out-Null
}
}
function Download-File {
param(
[Parameter(Mandatory=$true)]
[string]$Url,
[Parameter(Mandatory=$true)]
[string]$Destination
)
Write-Host "[*] Downloading file..."
Write-Host " URL : $Url"
Write-Host " OUT : $Destination"
try {
Invoke-WebRequest -Uri $Url -OutFile $Destination -UseBasicParsing -ErrorAction Stop
Write-Host "[OK] Download completed."
Write-Host ""
}
catch {
Write-Host "[ERROR] Failed to download: $Url"
Write-Host $_.Exception.Message
throw
}
}
function Extract-Zip {
param(
[Parameter(Mandatory=$true)]
[string]$ZipPath,
[Parameter(Mandatory=$true)]
[string]$DestDir
)
Write-Host "[*] Extracting ZIP:"
Write-Host " $ZipPath"
Write-Host " -> $DestDir"
# Make sure destination directory exists and is a directory
Ensure-EmptyDirectory -Path $DestDir
# Temporary extraction folder inside destination
$TmpExtract = Join-Path $DestDir "__tmp_extract__"
Ensure-EmptyDirectory -Path $TmpExtract
Write-Host "[DEBUG] PowerShell command:"
Write-Host " Expand-Archive -LiteralPath `"$ZipPath`" -DestinationPath `"$TmpExtract`" -Force"
try {
Expand-Archive -LiteralPath $ZipPath -DestinationPath $TmpExtract -Force -ErrorAction Stop
}
catch {
Write-Host "[ERROR] Failed to extract ZIP with Expand-Archive: $ZipPath"
Write-Host $_.Exception.Message
throw
}
# Check extracted entries
$entries = Get-ChildItem -LiteralPath $TmpExtract
if (-not $entries -or $entries.Count -eq 0) {
Write-Host "[ERROR] No entries were extracted from ZIP: $ZipPath"
throw "ZIP appears to be empty or extraction failed."
}
if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) {
Write-Host "[*] Detected single root directory inside ZIP. Flattening..."
# Move children of the single root directory into destination
$innerItems = Get-ChildItem -LiteralPath $entries[0].FullName
foreach ($item in $innerItems) {
Move-Item -LiteralPath $item.FullName -Destination $DestDir -Force
}
}
else {
Write-Host "[*] ZIP has multiple top-level entries. Copying all..."
foreach ($item in $entries) {
Move-Item -LiteralPath $item.FullName -Destination $DestDir -Force
}
}
# Clean up temp extraction folder
Remove-Item -LiteralPath $TmpExtract -Recurse -Force
Write-Host "[OK] ZIP extraction completed."
Write-Host ""
}
function Extract-TarGz {
param(
[Parameter(Mandatory=$true)]
[string]$TarGzPath,
[Parameter(Mandatory=$true)]
[string]$DestDir
)
Write-Host "[*] Extracting TAR.GZ:"
Write-Host " $TarGzPath"
Write-Host " -> $DestDir"
Ensure-EmptyDirectory -Path $DestDir
# Modern Windows ships with tar, but we validate its presence
$tarCmd = Get-Command tar -ErrorAction SilentlyContinue
if (-not $tarCmd) {
Write-Host "[ERROR] 'tar' command not found. Cannot extract TAR.GZ."
throw "tar command not found."
}
Write-Host "[DEBUG] tar command:"
Write-Host " tar -xzf `"$TarGzPath`" -C `"$DestDir`""
try {
& tar -xzf "$TarGzPath" -C "$DestDir"
if ($LASTEXITCODE -ne 0) {
throw "tar exit code $LASTEXITCODE"
}
Write-Host "[OK] TAR.GZ extraction completed."
Write-Host ""
}
catch {
Write-Host "[ERROR] Failed to extract TAR.GZ: $TarGzPath"
Write-Host $_.Exception.Message
throw
}
}
# ================================
# SET DOWNLOAD URLS BASED ON ARCH
# ================================
$PythonUrl = $null
$CurlUrl = $null
$YaraUrl = $null
$WamrUrl = $null
switch ($arch) {
"x64" {
# Python embeddable (x64)
$PythonUrl = "https://www.python.org/ftp/python/3.13.9/python-3.13.9-embeddable-amd64.zip"
# curl (x64, mingw)
$CurlUrl = "https://curl.se/windows/latest.cgi?p=win64-mingw.zip"
# YARA (x64, GitHub — as you specified)
$YaraUrl = "https://github.com/VirusTotal/yara/releases/download/v4.5.5/yara-4.5.5-2368-win64.zip"
# WAMR (x64 only)
$WamrUrl = "https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-2.4.3/iwasm-2.4.3-x86_64-windows-2022.tar.gz"
}
"arm64" {
# Python embeddable (ARM64)
$PythonUrl = "https://www.python.org/ftp/python/3.13.9/python-3.13.9-embeddable-arm64.zip"
# curl (ARM64)
$CurlUrl = "https://curl.se/windows/latest.cgi?p=win64a-mingw.zip"
# DO NOT install YARA/WAMR on ARM64
$YaraUrl = $null
$WamrUrl = $null
}
default {
# Treat anything else as x86
# Python embeddable (x86)
$PythonUrl = "https://www.python.org/ftp/python/3.13.9/python-3.13.9-embeddable-win32.zip"
# curl (x86)
$CurlUrl = "https://downloads.sourceforge.net/project/muldersoft/cURL/curl-8.17.0-win-x86-full.2025-11-09.zip";
# Do NOT install YARA/WAMR on x86 (same policy as before)
$YaraUrl = $null
$WamrUrl = $null
}
}
Write-Host "[*] Python URL: $PythonUrl"
Write-Host "[*] curl URL : $CurlUrl"
if ($YaraUrl) {
Write-Host "[*] YARA URL : $YaraUrl"
} else {
Write-Host "[*] YARA : skipped on this architecture"
}
if ($WamrUrl) {
Write-Host "[*] WAMR URL : $WamrUrl"
} else {
Write-Host "[*] WAMR : skipped on this architecture"
}
Write-Host ""
# ================================
# DOWNLOAD FILES
# ================================
$PythonZip = Join-Path $TmpDir "python.zip"
$CurlZip = Join-Path $TmpDir "curl.zip"
$YaraZip = Join-Path $TmpDir "yara.zip"
$WamrTgz = Join-Path $TmpDir "wamr.tar.gz"
try {
Download-File -Url $PythonUrl -Destination $PythonZip
Download-File -Url $CurlUrl -Destination $CurlZip
if ($YaraUrl) {
Download-File -Url $YaraUrl -Destination $YaraZip
}
if ($WamrUrl) {
Download-File -Url $WamrUrl -Destination $WamrTgz
}
}
catch {
Write-Host "[FATAL] Download phase failed."
exit 1
}
# ================================
# EXTRACT FILES
# ================================
try {
Extract-Zip -ZipPath $PythonZip -DestDir (Join-Path $TargetDir "python")
Extract-Zip -ZipPath $CurlZip -DestDir (Join-Path $TargetDir "curl")
if ($YaraUrl) {
Extract-Zip -ZipPath $YaraZip -DestDir (Join-Path $TargetDir "yara")
}
if ($WamrUrl) {
Extract-TarGz -TarGzPath $WamrTgz -DestDir (Join-Path $TargetDir "wamr")
}
}
catch {
Write-Host "[FATAL] Extraction phase failed."
exit 1
}
# ================================
# FINISH
# ================================
Write-Host "[*] All tools installed successfully."
Write-Host "[*] Installed into: $TargetDir"
Write-Host ""
exit 0

View File

@ -0,0 +1,231 @@
{
"title": "Korea Business Number Area Code",
"author": "Namhyeon Go <gnh1201@catswords.re.kr>, WelsonJS OSS team",
"website": "https://github.com/gnh1201/welsonjs",
"created_on": "2025-11-19",
"data": {
"seoul": [
100,
101,
104,
105,
106,
107,
108,
109,
110,
113,
114,
117,
119,
120,
145,
146,
147,
201,
204,
206,
209,
210,
211,
212,
214,
215,
217,
220,
230
],
"incheon": [
121,
122,
131,
137,
150,
234,
800
],
"busan": [
600,
602,
603,
605,
606,
607,
617,
621,
623
],
"daegu": [
500,
502,
503,
504,
514,
516
],
"gwangju": [
400,
408,
409,
410,
419
],
"daejeon": [
300,
305,
314,
318
],
"ulsan": [
610,
620
],
"sejong": [
320
],
"gyeonggi": [
123,
124,
125,
126,
127,
128,
129,
130,
132,
134,
135,
138,
140,
141,
142,
143,
144,
149,
151,
152,
200,
231,
232,
233,
235,
236
],
"gangwon": [
221,
222,
223,
224,
225,
226,
227
],
"chungbuk": [
301,
302,
303,
304,
317
],
"chungnam": [
307,
308,
310,
311,
312,
313,
316,
319
],
"jeonbuk": [
401,
402,
403,
404,
407,
418
],
"jeonnam": [
411,
412,
415,
416,
417
],
"gyeongbuk": [
505,
506,
507,
508,
510,
511,
512,
513,
515
],
"gyeongnam": [
608,
609,
611,
612,
613,
615,
624
],
"jeju": [
616
],
"p_seoul": [
116,
775
],
"p_incheon": [
172,
139
],
"p_gyeonggi": [
696,
276,
585,
133,
687,
509,
581,
557,
405,
727,
514,
371
],
"p_busan": [
825,
644,
449
],
"p_daejeon": [
306
],
"p_sejong": [
330,
698
],
"p_gwangju": [
256
],
"p_gyeongbuk": [
568
],
"p_chungnam": [
709,
294
],
"p_chungbuk": [
203,
136
],
"p_jeonbuk": [
586,
704
]
}
}

View File

@ -0,0 +1,57 @@
// korea_biz_area_checker.js
// Namhyeon Go <gnh1201@catswords.re.kr>, WelsonJS OSS team
// https://github.com/gnh1201/welsonjs
//
var FILE = require("lib/file");
var Office = require("lib/msoffice");
function main(args) {
// Business Area Code in Korea
console.log("> Business Area Code in Korea");
var data_biz_areacode = JSON.parse(FILE.readFile("data/korea_business_areacode.json")).data;
console.log(JSON.stringify(data_biz_areacode));
// Open the Microsoft Excel file
console.log("> Open the Microsoft Excel file");
var excel = new Office.Excel();
excel.open("data\\example.xlsx");
// Retrieve the business area code
for (var i = 3; i < 1233; i++) {
try {
// check the biz area name
console.log(">> check the biz area name");
var areaname = excel.getCellByPosition(i, 16).getValue();
if (!!areaname)
continue;
// check the biz number
console.log(">> check the biz number");
var biznumber = excel.getCellByPosition(i, 8).getValue();
if (!biznumber)
continue;
// match the biznumber to biz area code data
console.log(">> match the biznumber to biz area code data: " + biznumber);
var matched_areaname = "unknown";
for (var k in data_biz_areacode) {
var areacode = parseInt(biznumber.substring(0, 3));
if (data_biz_areacode[k].indexOf(areacode) > -1) {
matched_areaname = k;
break;
}
}
console.log(">> write the matched area name: " + matched_areaname);
excel.getCellByPosition(i, 16).setValue(matched_areaname);
} catch (e) {
excel.getCellByPosition(i, 16).setValue("unknown");
}
}
excel.saveAs("example_edited.xlsx");
excel.close();
}
exports.main = main;

View File

@ -15,6 +15,8 @@ function main(args) {
console.error("lib/http: Something wrong");
}
sleep(100000);
//Toolkit.create();
}

View File

@ -119,7 +119,11 @@ var HTTPObject = function(engine) {
} else if (this.engine == "CURL") {
this._interface = SHELL.create();
// the location of cURL binary
// set cURL executable file location
var default_curl_path = SYS.getAppDataDir() + "\\curl\\curl.exe";
if (FILE.fileExists(default_curl_path)) {
this.setBinPath(default_curl_path);
} else {
var arch = SYS.getArch();
if (arch.toLowerCase().indexOf("arm") > -1) {
this.setBinPath("bin\\arm64\\curl-" + this.curlVersion + "-win64a-mingw\\bin\\curl.exe");
@ -128,6 +132,7 @@ var HTTPObject = function(engine) {
} else {
this.setBinPath("bin\\x86\\curl-" + this.curlVersion + "-win32-mingw\\bin\\curl.exe");
}
}
// do not clear after calling the `exec`
this._interface.setIsPreventClear(true);

View File

@ -1,16 +1,17 @@
// ovftool.js
// Copyright 2019-2025, Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// SPDX-License-Identifier: GPL-3.0-or-later
// https://github.com/gnh1201/welsonjs
//
// Download OVFTool (Open Virtualization Format (OVF) Tool):
// https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest
//
var SYS = require("lib/system");
var SHELL = require("lib/shell");
var CRED = require("lib/credentials");
function OVFObject() {
this.binPath = "bin\\x64\\VMware-ovftool-4.6.3-24031167-win.x86_64\\ovftool\\ovftool.exe";
this.binPath = SYS.getAppDataDir() + "\\ovftool\\ovftool.exe";
this.hostname = "";
this.port = 443;
this.resourceName = "";
@ -66,7 +67,7 @@ function create() {
exports.setCredential = setCredential;
exports.create = create;
exports.VERSIONINFO = "Broadcom/VMware OVF Tool interface (ovftool.js) version 0.1.2";
exports.VERSIONINFO = "Broadcom/VMware OVF Tool interface (ovftool.js) version 0.1.3";
exports.AUTHOR = "gnh1201@catswords.re.kr";
exports.global = global;
exports.require = global.require;

View File

@ -1,5 +1,5 @@
// python3.js
// Copyright 2019-2025, Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// SPDX-License-Identifier: GPL-3.0-or-later
// https://github.com/gnh1201/welsonjs
//
@ -7,12 +7,17 @@
//
var SYS = require("lib/system");
var SHELL = require("lib/shell");
var FILE = require("lib/file");
function PythonObject() {
this.binPath = null;
this.version = "3.13.2";
this.create = function() {
var default_python3_path = SYS.getAppDataDir() + "\\python\\python.exe";
if (FILE.fileExists(default_python3_path)) {
this.setBinPath(default_python3_path);
} else {
var arch = SYS.getArch();
if (arch.toLowerCase().indexOf("arm") > -1) {
this.setBinPath("bin\\arm64\\python-" + this.version + "-embed-arm64\\python.exe");
@ -21,6 +26,7 @@ function PythonObject() {
} else {
this.setBinPath("bin\\x86\\python-" + this.version + "-embed-win32\\python.exe");
}
}
};
this.setBinPath = function(binPath) {
@ -45,6 +51,9 @@ function PythonObject() {
scriptName
].concat(args));
};
// Initialize default Python binary path based on current version and system arch
this.create();
}
exports.PythonObject = PythonObject;
@ -57,6 +66,6 @@ exports.execScript = function(scriptName, args) {
return (new PythonObject()).execScript(scriptName, args);
};
exports.VERSIONINFO = "Python Interface (python3.js) version 0.2.1";
exports.VERSIONINFO = "Python Interface (python3.js) version 0.2.2";
exports.global = global;
exports.require = global.require;

View File

@ -37,6 +37,10 @@ function getEnvString(envName) {
})(envName.toUpperCase());
}
function getAppDataDir() {
return getEnvString("APPDATA") + "\\WelsonJS";
}
function get32BitFolder() {
var base = getEnvString("WINDIR");
var syswow64 = base + "\\SysWOW64\\";
@ -198,6 +202,7 @@ function getProcessVersion() {
exports.createProcess = createProcess;
exports.getEnvString = getEnvString;
exports.getAppDataDir = getAppDataDir;
exports.get32BitFolder = get32BitFolder;
exports.isElevated = isElevated;
exports.getOS = getOS;
@ -219,6 +224,6 @@ exports.createShortcut = createShortcut;
exports.ping = ping;
exports.getProcessVersion = getProcessVersion;
exports.VERSIONINFO = "System Module (system.js) version 0.1.5";
exports.VERSIONINFO = "System Module (system.js) version 0.1.6";
exports.global = global;
exports.require = global.require;

View File

@ -1,15 +1,16 @@
// wamr.js
// Copyright 2019-2025, Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
// SPDX-License-Identifier: GPL-3.0-or-later
// https://github.com/gnh1201/welsonjs
//
// WAMR(WebAssembly Micro Runtime) integration for WelsonJS framework
// WAMR(WebAssembly Micro Runtime) integration
// https://github.com/bytecodealliance/wasm-micro-runtime
//
var SYS = require("lib/system");
var SHELL = require("lib/shell");
var WAMRObject = function() {
this.binPath = "bin\\iwasm";
this.binPath = SYS.getAppDataDir() + "\\wamr\\iwasm.exe";
this.verbose = 0;
this.stackSize = 0;
@ -60,3 +61,7 @@ var WAMRObject = function() {
exports.create = function() {
return new WAMRObject();
};
exports.VERSIONINFO = "WAMR(WebAssembly Micro Runtime) integration (wamr.js) version 0.1.1";
exports.global = global;
exports.require = global.require;

View File

@ -25,12 +25,24 @@ DisableWelcomePage=yes
DisableDirPage=yes
DisableProgramGroupPage=yes
LicenseFile=SECURITY.MD
ChangesAssociations=yes
; [Registry]
; Root: HKCR; Subkey: "welsonjs"; ValueType: "string"; ValueData: "URL:{cm:AppName}"; Flags: uninsdeletekey
; Root: HKCR; Subkey: "welsonjs"; ValueType: "string"; ValueName: "URL Protocol"; ValueData: ""
; Root: HKCR; Subkey: "welsonjs\DefaultIcon"; ValueType: "string"; ValueData: "{app}\app\favicon.ico,0"
; Root: HKCR; Subkey: "welsonjs\shell\open\command"; ValueType: "string"; ValueData: "cscript ""{app}\app.js"" uriloader ""%1"""
Root: HKCR; Subkey: "WelsonJS.Script"; ValueType: string; ValueData: "WelsonJS Script"; Flags: uninsdeletekey
Root: HKCR; Subkey: "WelsonJS.Script\DefaultIcon"; ValueType: string; ValueData: "{app}\app\favicon.ico,0"; Flags: uninsdeletekey
Root: HKCR; Subkey: "WelsonJS.Script\shell"; ValueType: string; ValueData: "open"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "WelsonJS.Script\shell\open"; ValueType: string; ValueData: "Run with WelsonJS"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "WelsonJS.Script\shell\open\command"; ValueType: string; ValueData: """{app}\bin\x86\WelsonJS.Launcher.exe"" --file ""%1"""; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".js"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".ts"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".re"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".res"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".ls"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".coffee"; ValueType: string; ValueData: "WelsonJS.Script"; Flags: uninsdeletevalue
[Files]
Source: "app.js"; DestDir: "{app}";
@ -72,6 +84,7 @@ Name: "{group}\Uninstall {cm:AppName}"; Filename: "{uninstallexe}"; AfterInstall
; Filename: {app}\bin\gtk2-runtime-2.24.33-2021-01-30-ts-win64.exe;
; Filename: {app}\bin\nmap-7.92\VC_redist.x86.exe;
; Filename: {app}\bin\nmap-7.92\npcap-1.50.exe;
Filename: "powershell.exe"; Parameters: "-ExecutionPolicy Bypass -NoProfile -File ""{app}\afterInstall.ps1"""; WorkingDir: "{app}"; Flags: nowait
Filename: {app}\installService.bat; Flags: nowait
Filename: {app}\bin\x86\WelsonJS.Launcher.exe; Flags: nowait