aboutsummaryrefslogtreecommitdiffstats
path: root/packaging/win/ensure-node-path.ps1
blob: f9b6f68ae7efc8a8b081b6489f7363ba461d6cfd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<#
.SYNOPSIS
    Add the bundled node-runtime directory to the per-user PATH, if it is not
    there already.

.DESCRIPTION
    build/installer.nsh's customInstall does this at install time for the NSIS
    Full target (HKCU\Environment, no elevation -- a per-user registry write
    needs none). An AppX/MSIX install has no install-time hook at all, elevated
    or not -- not a signing/elevation gap like the firewall rule or
    service-mode, but the more basic fact that MSIX runs no custom code
    whatsoever during setup. So the MSIX target calls this itself, once, on
    first launch (main.js's winEnsureNodeOnPath()) instead.

    Idempotent and safe to run on every launch of any packaged Windows build,
    NSIS Full included: if the installer already added the entry, this is a
    fast no-op query. Never touches PATH for a Light install (no bundled
    node-runtime to add) -- the caller only invokes this when
    hasBundledNode() is true.

    Broadcasts WM_SETTINGCHANGE afterward so already-open shells notice --
    same as the installer's own SendMessage call. New shells pick it up
    either way.

.PARAMETER NodeDir
    Full path to the node-runtime directory to add.
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)][string]$NodeDir
)

$ErrorActionPreference = "Stop"

$key = "Registry::HKEY_CURRENT_USER\Environment"
$current = (Get-ItemProperty -Path $key -Name "Path" -ErrorAction SilentlyContinue).Path
if ($null -eq $current) { $current = "" }

$parts = $current -split ";" | Where-Object { $_ -ne "" }
$already = $parts | Where-Object { $_.TrimEnd('\') -ieq $NodeDir.TrimEnd('\') }
if ($already) {
    Write-Output "already present"
    exit 0
}

$next = if ($parts.Count -gt 0) { ($parts + $NodeDir) -join ";" } else { $NodeDir }
# ExpandString, not String -- matches installer.nsh's WriteRegExpandStr, so any
# %VAR% another entry already carries on this machine keeps expanding.
New-ItemProperty -Path $key -Name "Path" -Value $next -PropertyType ExpandString -Force | Out-Null

Add-Type -Namespace MeshBay -Name NativeMethods -MemberDefinition @"
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public static extern System.IntPtr SendMessageTimeout(System.IntPtr hWnd, uint Msg, System.UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out System.UIntPtr lpdwResult);
"@
$HWND_BROADCAST = [IntPtr]0xffff
$WM_SETTINGCHANGE = 0x1a
$result = [UIntPtr]::Zero
[MeshBay.NativeMethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 5000, [ref]$result) | Out-Null

Write-Output "added"