Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(iec): Rename 'Invoke-ExternalCommand()' to 'Start-ExternalProcess()' and support EnvVars/WorkingDirectory #5124

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 92 additions & 36 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -592,65 +592,116 @@ function is_local($path) {
# operations

function run($exe, $arg, $msg, $continue_exit_codes) {
Show-DeprecatedWarning $MyInvocation 'Invoke-ExternalCommand'
Invoke-ExternalCommand -FilePath $exe -ArgumentList $arg -Activity $msg -ContinueExitCodes $continue_exit_codes
Show-DeprecatedWarning $MyInvocation 'Start-ExternalProcess'
Start-ExternalProcess -FilePath $exe -ArgumentList $arg -Prompt $msg -ContinueExitCodes $continue_exit_codes
}

function Invoke-ExternalCommand {
[CmdletBinding(DefaultParameterSetName = "Default")]
[CmdletBinding(DefaultParameterSetName = 'Default')]
[OutputType([Boolean])]
param (
[Parameter(Mandatory = $true,
Position = 0)]
[Alias("Path")]
[Parameter(Mandatory = $true, Position = 0)]
[Alias('Path')]
[ValidateNotNullOrEmpty()]
[String]
$FilePath,
[Parameter(Position = 1)]
[Alias("Args")]
[Alias('Args')]
[String[]]
$ArgumentList,
[Parameter(ParameterSetName = "UseShellExecute")]
[Parameter(ParameterSetName = 'UseShellExecute')]
[Switch]
$RunAs,
[Parameter(ParameterSetName = "UseShellExecute")]
[Parameter(ParameterSetName = 'UseShellExecute')]
[Switch]
$Quiet,
[Alias("Msg")]
[Alias('Msg')]
[String]
$Activity,
[Alias("cec")]
[Alias('cec')]
[Hashtable]
$ContinueExitCodes,
[Parameter(ParameterSetName = "Default")]
[Alias("Log")]
[Parameter(ParameterSetName = 'Default')]
[Alias('Log')]
[String]
$LogPath
)
if ($Activity) {
Write-Host "$Activity " -NoNewline
Show-DeprecatedWarning $MyInvocation 'Start-ExternalProcess'
if ($RunAs) {
Start-ExternalProcess -FilePath $FilePath -ArgumentList $ArgumentList -Prompt $Activity -ContinueExitCodes $ContinueExitCodes -RunAs -Quiet:$Quiet
} else {
Start-ExternalProcess -FilePath $FilePath -ArgumentList $ArgumentList -Prompt $Activity -ContinueExitCodes $ContinueExitCodes -LogName $LogPath
}
}

function Start-ExternalProcess {
[CmdletBinding(DefaultParameterSetName = 'Default')]
[OutputType([Boolean])]
param (
[Parameter(Mandatory = $true, Position = 0)]
[Alias('PSPath', 'Path')]
[ValidateNotNullOrEmpty()]
[String]
$FilePath,
[Parameter(Position = 1)]
[Alias('Args')]
[String[]]
$ArgumentList,
[Parameter(ParameterSetName = 'Default')]
[String]
$WorkingDirectory,
[Parameter(ParameterSetName = 'UseShellExecute')]
[Switch]
$RunAs,
[Parameter(ParameterSetName = 'UseShellExecute')]
[Switch]
$Quiet,
[Alias('Msg')]
[String]
$Prompt,
[Alias('cec')]
[Hashtable]
$ContinueExitCodes,
[Parameter(ParameterSetName = 'Default')]
[Alias('EnvVar')]
[Hashtable]
$EnvironmentVariables,
[Parameter(ParameterSetName = 'Default')]
[Alias('LogPath')]
[String]
$LogName
)
if ($Prompt) {
Write-Host "$Prompt " -NoNewline
}
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo.FileName = $FilePath
$Process.StartInfo.UseShellExecute = $false
if ($LogPath) {
if ($LogName) {
if ($FilePath -match '^msiexec(.exe)?$') {
$ArgumentList += "/lwe `"$LogPath`""
$ArgumentList += "/lwe `"$LogName`""
} else {
$redirectToLogFile = $true
$Process.StartInfo.RedirectStandardOutput = $true
$Process.StartInfo.RedirectStandardError = $true
}
}
if ($RunAs) {
$Process.StartInfo.UseShellExecute = $true
$Process.StartInfo.Verb = 'RunAs'
} else {
$Process.StartInfo.RedirectStandardOutput = $true
$Process.StartInfo.RedirectStandardError = $true
if ($WorkingDirectory) {
$Process.StartInfo.WorkingDirectory = ensure $WorkingDirectory
}
}
if ($Quiet) {
$Process.StartInfo.UseShellExecute = $true
$Process.StartInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
}
if ($ArgumentList.Length -gt 0) {
if ($EnvironmentVariables) {
$EnvironmentVariables.GetEnumerator() | ForEach-Object { $Process.StartInfo.EnvironmentVariables.Add($_.Key, $_.Value) }
}
if ($ArgumentList) {
if ($FilePath -match '^((cmd|cscript|wscript|msiexec)(\.exe)?|.*\.(bat|cmd|js|vbs|wsf))$') {
$Process.StartInfo.Arguments = $ArgumentList -join ' '
} elseif ($Process.StartInfo.ArgumentList.Add) {
Expand All @@ -676,40 +727,45 @@ function Invoke-ExternalCommand {
try {
[void]$Process.Start()
} catch {
if ($Activity) {
Write-Host "error." -ForegroundColor DarkRed
if ($Prompt) {
Write-Host 'error.' -ForegroundColor DarkRed
}
error $_.Exception.Message
return $false
}
if ($redirectToLogFile) {
# we do this to remove a deadlock potential
# ref: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput?view=netframework-4.5#remarks
$stdoutTask = $Process.StandardOutput.ReadToEndAsync()
$stderrTask = $Process.StandardError.ReadToEndAsync()
}
# we do this to remove a deadlock potential
# ref: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput?view=netframework-4.5#remarks
$stdoutTask = $Process.StandardOutput.ReadToEndAsync()
$stderrTask = $Process.StandardError.ReadToEndAsync()
$Process.WaitForExit()
if ($redirectToLogFile) {
Out-UTF8File -FilePath $LogPath -Append -InputObject $stdoutTask.Result
Out-UTF8File -FilePath $LogPath -Append -InputObject $stderrTask.Result
Out-UTF8File -FilePath $LogName -Append -InputObject $stdoutTask.Result.Trim()
Out-UTF8File -FilePath $LogName -Append -InputObject $stderrTask.Result.Trim()
} else {
if ($stdoutTask.Result) {
$stdoutTask.Result.Trim() | Out-Default
}
if ($stderrTask.Result) {
$stderrTask.Result.Trim() | Out-Default
}
}
if ($Process.ExitCode -ne 0) {
if ($ContinueExitCodes -and ($ContinueExitCodes.ContainsKey($Process.ExitCode))) {
if ($Activity) {
Write-Host "done." -ForegroundColor DarkYellow
if ($Prompt) {
Write-Host 'done.' -ForegroundColor DarkYellow
}
warn $ContinueExitCodes[$Process.ExitCode]
return $true
} else {
if ($Activity) {
Write-Host "error." -ForegroundColor DarkRed
if ($Prompt) {
Write-Host 'error.' -ForegroundColor DarkRed
}
error "Exit code was $($Process.ExitCode)!"
return $false
}
}
if ($Activity) {
Write-Host "done." -ForegroundColor Green
if ($Prompt) {
Write-Host 'done.' -ForegroundColor Green
}
return $true
}
Expand Down
54 changes: 27 additions & 27 deletions lib/decompress.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function Expand-7zipArchive {
} else {
$7zPath = Get-HelperPath -Helper 7zip
}
$LogPath = "$(Split-Path $Path)\7zip.log"
$LogName = "$(Split-Path $Path)\7zip.log"
$DestinationPath = $DestinationPath.TrimEnd('\')
$ArgList = @('x', $Path, "-o$DestinationPath", '-xr!*.nsis', '-y')
$IsTar = ((strip_ext $Path) -match '\.tar$') -or ($Path -match '\.t[abgpx]z2?$')
Expand All @@ -42,22 +42,22 @@ function Expand-7zipArchive {
'Skip' { $ArgList += '-aos' }
'Rename' { $ArgList += '-aou' }
}
$Status = Invoke-ExternalCommand $7zPath $ArgList -LogPath $LogPath
$Status = Start-ExternalProcess $7zPath $ArgList -LogName $LogName
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogName)`n$(new_issue_msg $app $bucket 'decompress error')"
}
if (!$IsTar -and $ExtractDir) {
movedir "$DestinationPath\$ExtractDir" $DestinationPath | Out-Null
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path $LogName) {
Remove-Item $LogName -Force
}
if ($IsTar) {
# Check for tar
$Status = Invoke-ExternalCommand $7zPath @('l', $Path) -LogPath $LogPath
$Status = Start-ExternalProcess $7zPath @('l', $Path) -LogName $LogName
if ($Status) {
# get inner tar file name
$TarFile = (Select-String -Path $LogPath -Pattern '[^ ]*tar$').Matches.Value
$TarFile = (Select-String -Path $LogName -Pattern '[^ ]*tar$').Matches.Value
Expand-7zipArchive -Path "$DestinationPath\$TarFile" -DestinationPath $DestinationPath -ExtractDir $ExtractDir -Removal
} else {
abort "Failed to list files in $Path.`nNot a 7-Zip supported archive file."
Expand Down Expand Up @@ -95,7 +95,7 @@ function Expand-ZstdArchive {
$Removal
)
$ZstdPath = Get-HelperPath -Helper Zstd
$LogPath = Join-Path (Split-Path $Path) 'zstd.log'
$LogName = Join-Path (Split-Path $Path) 'zstd.log'
$DestinationPath = $DestinationPath.TrimEnd('\')
ensure $DestinationPath | Out-Null
$ArgList = @('-d', $Path, '--output-dir-flat', $DestinationPath, '-f', '-v')
Expand All @@ -107,16 +107,16 @@ function Expand-ZstdArchive {
# Remove original archive file
$ArgList += '--rm'
}
$Status = Invoke-ExternalCommand $ZstdPath $ArgList -LogPath $LogPath
$Status = Start-ExternalProcess $ZstdPath $ArgList -LogName $LogName
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogName)`n$(new_issue_msg $app $bucket 'decompress error')"
}
$IsTar = (strip_ext $Path) -match '\.tar$'
if (!$IsTar -and $ExtractDir) {
movedir (Join-Path $DestinationPath $ExtractDir) $DestinationPath | Out-Null
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path $LogName) {
Remove-Item $LogName -Force
}
if ($IsTar) {
# Check for tar
Expand Down Expand Up @@ -154,13 +154,13 @@ function Expand-MsiArchive {
$MsiPath = 'msiexec.exe'
$ArgList = @('/a', "`"$Path`"", '/qn', "TARGETDIR=`"$DestinationPath\SourceDir`"")
}
$LogPath = "$(Split-Path $Path)\msi.log"
$LogName = "$(Split-Path $Path)\msi.log"
if ($Switches) {
$ArgList += (-split $Switches)
}
$Status = Invoke-ExternalCommand $MsiPath $ArgList -LogPath $LogPath
$Status = Start-ExternalProcess $MsiPath $ArgList -LogName $LogName
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogName)`n$(new_issue_msg $app $bucket 'decompress error')"
}
if ($ExtractDir -and (Test-Path "$DestinationPath\SourceDir")) {
movedir "$DestinationPath\SourceDir\$ExtractDir" $OriDestinationPath | Out-Null
Expand All @@ -174,8 +174,8 @@ function Expand-MsiArchive {
if (($DestinationPath -ne (Split-Path $Path)) -and (Test-Path "$DestinationPath\$(fname $Path)")) {
Remove-Item "$DestinationPath\$(fname $Path)" -Force
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path $LogName) {
Remove-Item $LogName -Force
}
if ($Removal) {
# Remove original archive file
Expand All @@ -200,7 +200,7 @@ function Expand-InnoArchive {
[Switch]
$Removal
)
$LogPath = "$(Split-Path $Path)\innounp.log"
$LogName = "$(Split-Path $Path)\innounp.log"
$ArgList = @('-x', "-d$DestinationPath", $Path, '-y')
switch -Regex ($ExtractDir) {
'^[^{].*' { $ArgList += "-c{app}\$ExtractDir" }
Expand All @@ -210,12 +210,12 @@ function Expand-InnoArchive {
if ($Switches) {
$ArgList += (-split $Switches)
}
$Status = Invoke-ExternalCommand (Get-HelperPath -Helper Innounp) $ArgList -LogPath $LogPath
$Status = Start-ExternalProcess (Get-HelperPath -Helper Innounp) $ArgList -LogName $LogName
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogName)`n$(new_issue_msg $app $bucket 'decompress error')"
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path $LogName) {
Remove-Item $LogName -Force
}
if ($Removal) {
# Remove original archive file
Expand Down Expand Up @@ -274,17 +274,17 @@ function Expand-DarkArchive {
[Switch]
$Removal
)
$LogPath = "$(Split-Path $Path)\dark.log"
$LogName = "$(Split-Path $Path)\dark.log"
$ArgList = @('-nologo', '-x', $DestinationPath, $Path)
if ($Switches) {
$ArgList += (-split $Switches)
}
$Status = Invoke-ExternalCommand (Get-HelperPath -Helper Dark) $ArgList -LogPath $LogPath
$Status = Start-ExternalProcess (Get-HelperPath -Helper Dark) $ArgList -LogName $LogName
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogName)`n$(new_issue_msg $app $bucket 'decompress error')"
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path $LogName) {
Remove-Item $LogName -Force
}
if ($Removal) {
# Remove original archive file
Expand Down
6 changes: 3 additions & 3 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ function install_msi($fname, $dir, $msi) {

$continue_exit_codes = @{ 3010 = "a restart is required to complete installation" }

$installed = Invoke-ExternalCommand 'msiexec' $arg -Activity "Running installer..." -ContinueExitCodes $continue_exit_codes
$installed = Start-ExternalProcess 'msiexec' $arg -Prompt 'Running installer...' -ContinueExitCodes $continue_exit_codes
if(!$installed) {
abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
}
Expand Down Expand Up @@ -766,7 +766,7 @@ function install_prog($fname, $dir, $installer, $global) {
if($prog.endswith('.ps1')) {
& $prog @arg
} else {
$installed = Invoke-ExternalCommand $prog $arg -Activity "Running installer..."
$installed = Start-ExternalProcess $prog $arg -Prompt 'Running installer...'
if(!$installed) {
abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
}
Expand Down Expand Up @@ -819,7 +819,7 @@ function run_uninstaller($manifest, $architecture, $dir) {
if($exe.endswith('.ps1')) {
& $exe @arg
} else {
$uninstalled = Invoke-ExternalCommand $exe $arg -Activity "Running uninstaller..." -ContinueExitCodes $continue_exit_codes
$uninstalled = Start-ExternalProcess $exe $arg -Prompt 'Running uninstaller...' -ContinueExitCodes $continue_exit_codes
if(!$uninstalled) { abort "Uninstallation aborted." }
}
}
Expand Down