55 lines
1.5 KiB
PowerShell
55 lines
1.5 KiB
PowerShell
param(
|
|
[Parameter(Mandatory=$true)] [string]$Command,
|
|
[string]$WorkDir = $null
|
|
)
|
|
|
|
# 1. Resolve work directory.
|
|
if ([string]::IsNullOrEmpty($WorkDir)) {
|
|
$WorkDir = $PSScriptRoot
|
|
} else {
|
|
# Expand variables in WorkDir, such as $env:APPDATA.
|
|
$WorkDir = $ExecutionContext.InvokeCommand.ExpandString($WorkDir)
|
|
}
|
|
|
|
# Make sure the directory exists.
|
|
if (-not (Test-Path $WorkDir)) {
|
|
Write-Warning "`n[CMD] WARNING: The work dir does not exist, using ($WorkDir)"
|
|
$WorkDir = $PSScriptRoot
|
|
}
|
|
|
|
# 2. Expand variables in the command.
|
|
$ProjectRoot = Split-Path $PSScriptRoot -Parent
|
|
# Replace $PSScriptRoot with the project root path.
|
|
# Direct string replacement is the safest option for backslashes.
|
|
if ($Command.Contains('$PSScriptRoot')) {
|
|
$Command = $Command.Replace('$PSScriptRoot', $ProjectRoot)
|
|
}
|
|
|
|
# This allows commands such as "echo $env:USERNAME".
|
|
$Command = $ExecutionContext.InvokeCommand.ExpandString($Command)
|
|
|
|
Write-Host "`n[CMD] Execute: $Command" -ForegroundColor Gray
|
|
|
|
# 3. Start cmd.exe.
|
|
# /c closes cmd after the command completes.
|
|
# /s enables cmd quote handling for complex command strings.
|
|
$processOptions = @{
|
|
FilePath = "cmd.exe"
|
|
ArgumentList = "/s", "/c", "`"$Command`""
|
|
WorkingDirectory = $WorkDir
|
|
Wait = $true
|
|
NoNewWindow = $true
|
|
PassThru = $true
|
|
}
|
|
|
|
try {
|
|
$proc = Start-Process @processOptions
|
|
|
|
# 4. Check exit code.
|
|
if ($proc.ExitCode -ne 0) {
|
|
Write-Error "`n[CMD] Failed to execute, exit code: $($proc.ExitCode)"
|
|
}
|
|
} catch {
|
|
Write-Error "`n[CMD] Failed to start process: $_"
|
|
}
|