Remove all Machine handling of path modification, ensure to safely modify path

This commit is contained in:
confused-Techie 2024-03-17 23:54:48 -07:00
parent 3411fb731a
commit 90d71d0391
3 changed files with 97 additions and 157 deletions

View File

@ -20,14 +20,7 @@ export default class SystemPanel {
WinShell.fileHandler.isRegistered((i) => { this.refs.fileHandlerCheckbox.checked = i })
WinShell.fileContextMenu.isRegistered((i) => { this.refs.fileContextMenuCheckbox.checked = i })
WinShell.folderContextMenu.isRegistered((i) => { this.refs.folderContextMenuCheckbox.checked = i })
if (this.isLikelyUserInstall()) {
WinShell.pathUser.isRegistered((i) => { this.refs.addToPathCheckbox.checked = i })
} else {
WinShell.pathMachine.isRegistered((i) => { this.refs.addToPathMachineCheckbox.checked = i })
// Check if Pulsar is running as Admin. To know if the user can modify the machine path
WinShell.runningAsAdmin((i) => { this.refs.addToPathMachineCheckbox.disabled = !i })
}
WinShell.pathUser.isRegistered((i) => { this.refs.addToPathCheckbox.checked = i })
}
destroy () {
@ -120,63 +113,29 @@ export default class SystemPanel {
}
}
isLikelyUserInstall() {
let resourcePath = atom.applicationDelegate.getWindowLoadSettings().resourcePath;
if (resourcePath.includes("AppData\\Local\\Programs\\pulsar")) {
return true;
} else {
return false;
}
}
getPathUI() {
if (this.isLikelyUserInstall()) {
return (
<div className='control-group'>
<div className='controls'>
<div className='checkbox'>
<label for='system.windows.add-to-path'>
<input
ref='addToPathCheckbox'
id='system.windows.add-to-path'
className='input-checkbox'
type='checkbox'
onclick={(e) => {
this.setRegistration(WinShell.pathUser, e.target.checked)
}} />
<div className='setting-title'>Add Pulsar to PATH (User Install)</div>
<div className='setting-description'>
Add Pulsar to Windows PATH to enable CLI usage.
</div>
</label>
</div>
return (
<div className='control-group'>
<div className='controls'>
<div className='checkbox'>
<label for='system.windows.add-to-path'>
<input
ref='addToPathCheckbox'
id='system.windows.add-to-path'
className='input-checkbox'
type='checkbox'
onclick={(e) => {
this.setRegistration(WinShell.pathUser, e.target.checked)
}} />
<div className='setting-title'>Add Pulsar to PATH</div>
<div className='setting-description'>
Add Pulsar to Windows PATH to enable CLI usage.
</div>
</label>
</div>
</div>
);
} else {
return (
<div className='control-group'>
<div className='controls'>
<div className='checkbox'>
<label for='system.windows.add-to-path-machine'>
<input
ref='addToPathMachineCheckbox'
id='system.windows.add-to-path-machine'
className='input-checkbox'
type='checkbox'
onclick={(e) => {
this.setRegistration(WinShell.pathMachine, e.target.checked)
}} />
<div className='setting-title'>Add Pulsar to PATH (Machine Install)</div>
<div className='setting-description'>
Add Pulsar to Windows PATH for machine installs. Requires administrative privileges.
</div>
</label>
</div>
</div>
</div>
);
}
</div>
);
}
focus () {

View File

@ -3,97 +3,94 @@
# Example Usage:
# Pulsar User Installation:
# .\_.ps1 -installMode User -installdir "$INSTDIR" -remove 0
# .\_.ps1 -installdir "$INSTDIR" -remove 0
# Pulsar Machine Installation:
# .\_.ps1 -installMode Machine -installdir "$INSTDIR" -remove 0
# .\_.ps1 -installdir "$INSTDIR" -remove 0
# Pulsar User Uninstallation:
# .\_.ps1 -installMode User -installdir "$INSTDIR" -remove 1
# .\_.ps1 -installdir "$INSTDIR" -remove 1
# Pulsar Machine Uninstallation:
# .\_.ps1 -installMode Machine -installdir "$INSTDIR" -remove 1
# .\_.ps1 -installdir "$INSTDIR" -remove 1
param ($installMode,$installdir,$remove)
# For safe interaction with environment variables taken from:
# https://github.com/chocolatey/choco/blob/HEAD/src/chocolatey.resources/helpers/functions/Set-EnvironmentVariable.ps1
# https://github.com/chocolatey/choco/blob/HEAD/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariable.ps1
# https://github.com/chocolatey/choco/blob/HEAD/src/chocolatey.resources/helpers/functions/Install-ChocolateyPath.ps1
param ($installdir,$remove)
# When self-elevating, we can't pass a raw boolean. Meaning we accept anything then convert
$remove = [System.Convert]::ToBoolean($remove)
# Only when modifying the Machine PATH, it takes much longer than expected. So here's a loading bar
$prog = 1
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
if ($installMode -eq "Machine") {
# PowerShell needs to be running as Admin to modify the Machine Variables
# So lets attempt to self-elevate
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$processOptions = @{
FilePath = "PowerShell.exe"
Wait = $true
PassThru = $true
Verb = "RunAs"
ArgumentList = "-File `"" + $MyInvocation.MyCommand.Path + "`" -installMode $installMode -installdir `"" + $installdir + "`" -remove $remove"
}
Start-Process @processOptions
Exit
}
}
}
if (-not $remove) {
if ($installMode -eq "User" -or $installMode -eq "Machine") {
# We want to add Pulsar path values
$prog = 25
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
# Lets first save a copy of the users current path
$env:Path >> prior2addition.txt;
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$installdir\resources;$installdir\resources\app\ppm\bin", $installMode)
$originalPathToInstall = $installdir
$prog = 50
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
$pulsarPath = $installdir + "\resources";
$ppmPath = $installdir + "\resources\app\ppm\bin";
# While this originally attempting to use the string '%USERPROFILE%' to avoid taking
# space on the PATH, whatever reads this path at startup in Pulsar, can't handle
# the variable, and instead creates the directory of the same name
# within the current folder. But only when opened via the context menu, terminal
# is fine.
$exitCode = [Environment]::SetEnvironmentVariable("ATOM_HOME", "$env:UserProfile\.pulsar", $installMode)
# Get the current PATH variable
$envPath = $env:PATH;
if (!$envPath.toLower().Contains($installdir.ToLower())) {
# we don't already have the correct environment variable
$actualPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User);
$prog = 100
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
$statementTerminator = ";";
Exit $exitCode
$pathToInstall = $pulsarPath + $statementTerminator + $ppmPath + $statementTerminator;
# Does the path end in ';'?
$hasStatementTerminator = $actualPath -ne $null -and $actualPath.EndsWith($statementTerminator);
# If the last digit is not ';', then add it
if (!$hasStatementTerminator -and $actualPath -ne $null) {
$pathToInstall = $statementTerminator + $pathToInstall;
}
$actualPath = $actualPath + $pathToInstall;
# Now to actually set the path to the system
$registryType = [Microsoft.Win32.RegistryValueKind]::ExpandString;
$keyHive = "HKEY_CURRENT_USER";
$registryKey = "Environment";
$exitCode = [Microsoft.Win32.Registry]::SetValue($keyHive + "\" + $registryKey, "Path", $actualPath, [System.EnvironmentVariableTarget]::User);
Exit $exitCode;
} else {
Write-Host "Pulsar is already present on the User PATH.";
}
} else {
if ($installMode -eq "User" -or $installMode -eq "Machine") {
# We want to remove Pulsar from the user path
$prog = 25
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
# Lets first save a copy of the users current path
$env:Path >> prior2removal.txt;
$path = [Environment]::GetEnvironmentVariable("Path", $installMode)
$pulsarPath = $installdir + "\resources";
$ppmPath = $installdir + "\resources\app\ppm\bin";
$prog = 50
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
# Get the current PATH variable
$envPath = $env:PATH;
if ($envPath.toLower().Contains($installdir.ToLower())) {
# the install dir is in fact on the path
$actualPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User);
# Remove unwanted element from path
$path = ($path.Split(";") | Where-Object { $_ -ne "$installdir\resources" }) -join ";"
$path = ($path.Split(";") | Where-Object { $_ -ne "$installdir\resources\app\ppm\bin" }) -join ";"
$actualPath = ($actualPath.Split(";") | Where-Object { $_ -ne $ppmPath }) -join ";";
# Order is important, as Pulsar's path INCLUDES ppm's path
$actualPath = ($actualPath.Split(";") | Where-Object { $_ -ne $pulsarPath }) -join ";";
$prog = 75
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
# Now to actually set the path to the system
$registryType = [Microsoft.Win32.RegistryValueKind]::ExpandString;
$keyHive = "HKEY_CURRENT_USER";
$registryKey = "Environment";
# Set our new path
[Environment]::SetEnvironmentVariable("Path", $path, $installMode)
$exitCode = [Microsoft.Win32.Registry]::SetValue($keyHive + "\" + $registryKey, "Path", $actualPath, [System.EnvironmentVariableTarget]::User);
$prog = 90
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
# Set ATOM_HOME path
$exitCode = [Environment]::SetEnvironmentVariable("ATOM_HOME", $null, $installMode)
$prog = 100
Write-Progress -Activity "Modifying Pulsar ($installdir) on the PATH..." -Status "$prog% Complete:" -PercentComplete $prog
Exit $exitCode
} # Else we have been given bad params, and will silently exit
Exit $exitCode;
} else {
Write-Host "Pulsar is not present on the User PATH.";
}
}

View File

@ -74,27 +74,17 @@ class ShellOption {
}
class PathOption {
constructor(installType) {
// installType MUST be 'User' or 'Machine'
constructor() {
this.HKPATH;
this.hive;
this.installReg = "\\SOFTWARE\\0949b555-c22c-56b7-873a-a960bdefa81f";
this.installMode = installType;
if (installType === "User") {
this.HKPATH = "\\Environment";
this.hive = "HKCU";
} else if (installType === "Machine") {
this.HKPATH = "\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
this.hive = "HKLM";
}
// We no longer support an `installType`
// Only managing the path of the current user
this.HKPATH = "\\Environment";
this.hive = "HKCU";
// Unfortunately, we can only manage the PATH for a per user installation.
// While the PowerShell script does support setting the PATH for a Machine
// install, we can't yet check that.
// https://github.com/fresc81/node-winreg/tree/1.2.1#troubleshooting
// This can only be done if Pulsar is run as Admin, with a user with Admin privs
// So we will pretend a user install is all that matters here
this.isRegistered = this.isRegistered.bind(this);
this.register = this.register.bind(this);
this.deregister = this.deregister.bind(this);
@ -129,8 +119,8 @@ class PathOption {
register(callback) {
this.getPulsarPath().then((pulsarPath) => {
const child = ChildProcess.execFile(
`${pulsarPath}\\resources\\modifyWindowsPath.ps1`,
['-installMode', this.installMode, '-installdir', `"${pulsarPath}"`, '-remove', '0'],
`"${pulsarPath}\\resources\\modifyWindowsPath.ps1"`,
['-installdir', `"${pulsarPath}"`, '-remove', '0'],
{ shell: "powershell.exe" },
(error, stdout, stderr) =>
{
@ -151,8 +141,8 @@ class PathOption {
if (isRegistered) {
this.getPulsarPath().then((pulsarPath) => {
const child = ChildProcess.execFile(
`${pulsarPath}\\resources\\modifyWindowsPath.ps1`,
['-installMode', this.installMode, '-installdir', `"${pulsarPath}"`, '-remove', '1'],
`"${pulsarPath}\\resources\\modifyWindowsPath.ps1"`,
['-installdir', `"${pulsarPath}"`, '-remove', '1'],
{ shell: "powershell.exe" },
(error, stdout, stderr) =>
{
@ -188,12 +178,7 @@ class PathOption {
reject("Unable to find Pulsar Install Path");
}
// When we are modifying Machine values, we can't accept spaces in the
// path. There's likely some combination of escapes to fix this, but
// I was unable to find them. For now we will check for the default
// Machine install location, and remove the space.
let safePulsarPath = pulsarPath.replace("Program Files", "PROGRA~1");
resolve(safePulsarPath);
resolve(pulsarPath);
}
});
});
@ -241,4 +226,3 @@ exports.folderBackgroundContextMenu = new ShellOption(
JSON.parse(JSON.stringify(contextParts).replace('%1', '%V'))
);
exports.pathUser = new PathOption("User");
exports.pathMachine = new PathOption("Machine");