Merge pull request #375 from gnh1201/dev

Fix #374 (postInstall.ps1)
This commit is contained in:
Namhyeon Go 2025-12-21 00:44:42 +09:00 committed by GitHub
commit ff29abd16f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 134 additions and 33 deletions

View File

@ -1,5 +1,6 @@
# WelsonJS post-install script
# Namhyeon Go <gnh1201@catswords.re.kr>, and Catswords OSS contributors.
# Updated on: 2025-12-21
# https://github.com/gnh1201/welsonjs
# ================================
@ -34,11 +35,14 @@ Write-Host $logo
# SCRIPT ROOT RESOLUTION
# ================================
# Ensure $ScriptRoot is available even on older PowerShell
if (-not (Get-Variable -Name PSScriptRoot -ErrorAction SilentlyContinue)) {
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$ScriptRoot = if ($PSScriptRoot) {
$PSScriptRoot
}
elseif ($MyInvocation.MyCommand.Path) {
Split-Path -Parent $MyInvocation.MyCommand.Path
}
else {
$ScriptRoot = $PSScriptRoot
(Get-Location).Path
}
# ================================
@ -49,7 +53,11 @@ $urlsFilePath = Join-Path $ScriptRoot "data/DownloadUrls.psd1"
if (Test-Path $urlsFilePath) {
try {
$DownloadUrls = Import-PowerShellDataFile -Path $urlsFilePath
if (Get-Command Import-PowerShellDataFile -ErrorAction SilentlyContinue) {
$DownloadUrls = Import-PowerShellDataFile -Path $urlsFilePath
} else {
$DownloadUrls = Invoke-Expression (Get-Content $urlsFilePath -Raw) # Tested in Windows 8.1
}
}
catch {
Write-Host "[WARN] Failed to load DownloadUrls.psd1. Falling back to empty URL table."
@ -122,6 +130,12 @@ if ($TelemetryProvider -and $TelemetryProvider.ToLower() -eq "posthog") {
}
if ($finalDistinctId -and $finalDistinctId.Trim() -ne "") {
# Get current script file name
$scriptName = if (Get-Variable -Name PSCommandPath -ErrorAction SilentlyContinue) {
Split-Path $PSCommandPath -Leaf
} else {
Split-Path $MyInvocation.MyCommand.Path -Leaf
}
# Build single event payload for PostHog /i/v0/e endpoint
$body = @{
@ -132,7 +146,7 @@ if ($TelemetryProvider -and $TelemetryProvider.ToLower() -eq "posthog") {
product = "welsonjs"
version = $Version
os = "windows"
source = "post-install.ps1"
source = $scriptName
components = $Components # Keep raw string here
}
timestamp = (Get-Date).ToString("o") # ISO 8601 format
@ -279,6 +293,20 @@ function Download-File {
Write-Host " $Url"
Write-Host " -> $DestinationPath"
# Fix TLS connectivity issues (Tested in Windows 8.1)
try {
$protocol = [Net.SecurityProtocolType]::Tls12 -bor `
[Net.SecurityProtocolType]::Tls11 -bor `
[Net.SecurityProtocolType]::Tls
try {
$protocol = $protocol -bor [Enum]::Parse([Net.SecurityProtocolType], 'Tls13')
} catch {}
[Net.ServicePointManager]::SecurityProtocol = $protocol
}
catch {
Write-Host "[WARN] TLS configuration failed: $($_.Exception.Message)"
}
# Ensure destination directory exists
$destDir = Split-Path -Parent $DestinationPath
if ($destDir -and -not (Test-Path $destDir)) {
@ -304,7 +332,60 @@ function Download-File {
}
if (-not $success) {
throw "Failed to download $Url after $maxRetries attempts."
Write-Host "[WARN] PowerShell download failed. Falling back to curl."
$curlPath = Join-Path $ScriptRoot "bin\x86\curl.exe"
if (-not (Test-Path $curlPath)) {
throw "curl not found at $curlPath"
}
$curlArgs = @(
"-L"
"--fail"
"--retry", "3"
"--retry-delay", "5"
"-o", $DestinationPath
$Url
)
$proc = Start-Process -FilePath $curlPath -ArgumentList $curlArgs -NoNewWindow -Wait -PassThru
if ($proc.ExitCode -ne 0 -or -not (Test-Path $DestinationPath)) {
throw "curl download failed with exit code $($proc.ExitCode)."
}
}
}
function Invoke-7zr {
param(
[Parameter(Mandatory = $true)]
[string[]]$Arguments,
[Parameter(Mandatory = $false)]
[string[]]$PipeToArguments
)
$sevenZip = Join-Path $ScriptRoot "bin\x86\7zr.exe"
if (-not (Test-Path $sevenZip)) {
throw "7zr.exe is missing: $sevenZip"
}
Write-Host "[INFO] Using 7zr.exe:"
Write-Host " $sevenZip"
Write-Host "[DEBUG] 7zr args:"
Write-Host " $($Arguments -join ' ')"
if ($PipeToArguments) {
Write-Host "[DEBUG] 7zr pipe-to args:"
Write-Host " $($PipeToArguments -join ' ')"
& $sevenZip @Arguments | & $sevenZip @PipeToArguments
}
else {
& $sevenZip @Arguments
}
if ($LASTEXITCODE -ne 0) {
throw "7zr exited with code $LASTEXITCODE."
}
}
@ -312,6 +393,7 @@ function Extract-CompressedFile {
param(
[Parameter(Mandatory = $true)]
[string]$CompressedPath,
[Parameter(Mandatory = $true)]
[string]$DestinationDirectory
)
@ -320,32 +402,46 @@ function Extract-CompressedFile {
Write-Host " $CompressedPath"
Write-Host " -> $DestinationDirectory"
# Ensure destination directory exists (clean)
Ensure-EmptyDirectory -Path $DestinationDirectory
# Temporary extraction workspace
$tmpExtractDir = Join-Path $DestinationDirectory "_tmp_extract"
Ensure-EmptyDirectory -Path $tmpExtractDir
# Extract all
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($CompressedPath, $tmpExtractDir)
$extractedOk = $false
$zipErrorMsg = $null
# Detect source root to move from
# Try ZipFile first
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop
[System.IO.Compression.ZipFile]::ExtractToDirectory($CompressedPath, $tmpExtractDir)
$extractedOk = $true
}
catch {
$zipErrorMsg = $_.Exception.Message
Write-Host "[WARN] ZipFile extraction failed. Falling back to 7zr.exe."
Write-Host " $zipErrorMsg"
}
# Fallback: 7zr.exe
if (-not $extractedOk) {
Invoke-7zr -Arguments @("x", $CompressedPath, "-o$tmpExtractDir", "-y")
$extractedOk = $true
}
# Detect root folder unwrap
$entries = Get-ChildItem -Path $tmpExtractDir -Force
$SourceRoot = $tmpExtractDir
if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) {
# ZIP contains exactly one top-level folder → unwrap that folder
$SourceRoot = $entries[0].FullName
Write-Host "[*] Detected single root folder inside zip: $($entries[0].Name)"
Write-Host "[*] Detected single root folder inside archive: $($entries[0].Name)"
Write-Host "[*] Unwrapping folder content..."
}
else {
Write-Host "[*] Extracting multi-item archive (no root folder unwrapping needed)."
}
# Move all items from source root to final destination
# Move items into final destination
Get-ChildItem -Path $SourceRoot -Force | ForEach-Object {
$targetPath = Join-Path $DestinationDirectory $_.Name
@ -355,7 +451,6 @@ function Extract-CompressedFile {
Move-Item -Path $_.FullName -Destination $targetPath
}
# Cleanup
Remove-Item -Path $tmpExtractDir -Recurse -Force
}
@ -363,6 +458,7 @@ function Extract-TarGzArchive {
param(
[Parameter(Mandatory = $true)]
[string]$ArchivePath,
[Parameter(Mandatory = $true)]
[string]$DestinationDirectory
)
@ -373,27 +469,27 @@ function Extract-TarGzArchive {
Ensure-EmptyDirectory -Path $DestinationDirectory
# Validate tar availability
# Try tar first
$tarCommand = Get-Command tar -ErrorAction SilentlyContinue
if (-not $tarCommand) {
Write-Host "[ERROR] 'tar' command not found."
throw "tar not available on this system."
}
if ($tarCommand) {
Write-Host "[DEBUG] tar command:"
Write-Host " tar -xzf `"$ArchivePath`" -C `"$DestinationDirectory`""
Write-Host "[DEBUG] tar command:"
Write-Host " tar -xzf `"$ArchivePath`" -C `"$DestinationDirectory`""
try {
& tar -xzf "$ArchivePath" -C "$DestinationDirectory"
if ($LASTEXITCODE -ne 0) {
throw "tar exited with code $LASTEXITCODE."
}
return
}
catch {
throw "Failed to extract TAR.GZ archive: $($_.Exception.Message)"
}
Write-Host "[WARN] 'tar' not found. Falling back to 7zr.exe."
Invoke-7zr `
-Arguments @("x", $ArchivePath, "-so") `
-PipeToArguments @("x", "-ttar", "-si", "-o$DestinationDirectory", "-y")
}
# ================================
# COMPRESSED / INSTALLER PATHS
# ================================

View File

@ -1,5 +1,5 @@
; @created_on 2020-06-26
; @updated_on 2025-12-01
; @updated_on 2025-12-20
; @author Namhyeon Go <gnh1201@catswords.re.kr> and Catswords OSS contributors.
[Setup]
@ -49,7 +49,7 @@ Root: HKCR; Subkey: "{cm:AppName}.Script"; ValueType: string; ValueData: "{cm:Ap
Root: HKCR; Subkey: "{cm:AppName}.Script\DefaultIcon"; ValueType: string; ValueData: "{app}\app\favicon.ico,0"; Flags: uninsdeletekey
Root: HKCR; Subkey: "{cm:AppName}.Script\shell"; ValueType: string; ValueData: "open"; Components: artifacts; Flags: uninsdeletevalue
Root: HKCR; Subkey: "{cm:AppName}.Script\shell\open"; ValueType: string; ValueData: "Run with {cm:AppName}"; Components: artifacts; Flags: uninsdeletevalue
Root: HKCR; Subkey: "{cm:AppName}.Script\shell\open\command"; ValueType: string; ValueData: """{userappdata}\{cm:AppName}\bin\WelsonJS.Launcher.exe"" --file ""%1"""; Components: artifacts; Flags: uninsdeletevalue
Root: HKCR; Subkey: "{cm:AppName}.Script\shell\open\command"; ValueType: string; ValueData: """{app}\bin\x86\WelsonJS.Launcher.exe"" --file ""%1"""; Components: artifacts; Flags: uninsdeletevalue
Root: HKCR; Subkey: "{cm:AppName}.Script\ScriptEngine"; ValueType: string; ValueData: "JScript"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "{cm:AppName}.Script\ScriptHostEncode"; ValueType: string; ValueData: "{{85131630-480C-11D2-B1F9-00C04F86C324}}"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".js"; ValueType: string; ValueData: "{cm:AppName}.Script"; Components: fileassoc; Flags: uninsdeletevalue;
@ -75,6 +75,11 @@ Source: "helloworld.*"; DestDir: "{app}";
Source: "app\*"; DestDir: "{app}/app"; Flags: ignoreversion recursesubdirs;
Source: "lib\*"; DestDir: "{app}/lib"; Flags: ignoreversion recursesubdirs;
; Source: "bin\*"; Excludes: "installer\*"; DestDir: "{app}/bin"; Flags: ignoreversion recursesubdirs;
Source: "bin\x86\7zr.exe"; DestDir: "{app}/bin/x86"; Flags: ignoreversion recursesubdirs;
Source: "bin\x86\curl.exe"; DestDir: "{app}/bin/x86"; Flags: ignoreversion recursesubdirs;
Source: "bin\x86\curl-ca-bundle.crt"; DestDir: "{app}/bin/x86"; Flags: ignoreversion recursesubdirs;
Source: "bin\x86\WelsonJS.Launcher.exe"; DestDir: "{app}/bin/x86"; Flags: ignoreversion recursesubdirs;
Source: "bin\x86\WelsonJS.Launcher.exe.config"; DestDir: "{app}/bin/x86"; Flags: ignoreversion recursesubdirs;
Source: "data\*"; Excludes: "*-apikey.txt"; DestDir: "{app}/data"; Flags: ignoreversion recursesubdirs;
; Source: "node_modules\*"; DestDir: "{app}/node_modules"; Flags: ignoreversion recursesubdirs;
; Source: "bower_components\*"; DestDir: "{app}/node_modules"; Flags: ignoreversion recursesubdirs;
@ -87,14 +92,14 @@ Name: "{app}\tmp";
; Type: files; Name: "{app}\defaultService.js"
[Icons]
Name: "{group}\Start {cm:AppName} Launcher"; Filename: "{userappdata}\{cm:AppName}\bin\WelsonJS.Launcher.exe"; Components: artifacts; AfterInstall: SetElevationBit('{group}\Start {cm:AppName} Launcher.lnk');
Name: "{group}\Start {cm:AppName} Launcher"; Filename: "{app}\bin\x86\WelsonJS.Launcher.exe"; Components: artifacts; AfterInstall: SetElevationBit('{group}\Start {cm:AppName} Launcher.lnk');
Name: "{group}\Test {cm:AppName}"; Filename: "{app}\bootstrap.bat"; AfterInstall: SetElevationBit('{group}\Test {cm:AppName}.lnk');
Name: "{group}\Uninstall {cm:AppName}"; Filename: "{uninstallexe}"; AfterInstall: SetElevationBit('{group}\Uninstall {cm:AppName}.lnk');
[Run]
Filename: "powershell.exe"; Parameters: "-ExecutionPolicy Bypass -NoProfile -File ""{app}\postInstall.ps1"" -TelemetryProvider posthog -TelemetryApiKey ""{cm:PostHogApiKey}"" -Version ""{cm:AppVersion}"" -DistinctId ""{computername}"" -Components ""{code:GetSelectedComponents}"""; WorkingDir: "{app}"; Flags: waituntilterminated
Filename: {app}\installService.bat; Components: artifacts; Flags: nowait
Filename: "{userappdata}\{cm:AppName}\bin\WelsonJS.Launcher.exe"; Components: artifacts; Flags: nowait
Filename: "{app}\installService.bat"; Components: artifacts; Flags: nowait
Filename: "{app}\bin\x86\WelsonJS.Launcher.exe"; Components: artifacts; Flags: nowait
[UninstallRun]
Filename: {app}\uninstallService.bat; Components: artifacts; Flags: waituntilterminated