Home > Back-end >  Get Ctrl-C to work better on invoke-expression for powershell?
Get Ctrl-C to work better on invoke-expression for powershell?

Time:12-29

I'm doing an invoke-expression of an old console command written in C and I don't have control over the C source code... But, I think it's trapping the Ctrl-C to prevent the command line from interrupting it... Thus, when I invoke-expression from my powershell script there's no way to break the execution using ctrl-C and it locks my terminal and I need to keep killing and restarting my terminal window... which is super annoying...

Is there a way to make sure that powershell gets the ctrl-C instead of the C program when starting the C program using invoke-expression? Like maybe, I can refuse to give stdin to the C program, and let powershell have it instead? or maybe there's some solution where stdin goes to a different powershell thread that waits for a ctrl-c and then kills the invoke-expression thread..

Example:

PS> $cmd = <path_to_misbehaving_cpp_program_that_doesnt_Allow_ctrl_c_To_break_it>

PS> invoke-expression $cmd
# now here if I ctrl-C I can't break out of the invoke-expression....
# But I need this capability to ctrl-C
#  to break the script and terminate the
#  invoke expression of the C   program.

CodePudding user response:

Starting and stopping (killing) a process from within powershell:

Use the Start-Process cmdlet to start the other program. If you use the -PassThru switch you get back the information witch process was started.

$Proc = Start-Process powershell.exe -ArgumentList '-command "sleep 60" '  -PassThru

This process can easily be killed with Stop-Process even if it is supposed to run another 60 seconds:

$Proc | Stop-Process

Edit:

Now with exit code (Thx @mklement0 for the Wait)

$Proc.WaitForExit()
$Proc.ExitCode

CodePudding user response:

The trick to get it to respond to ctrl-c was to pipe $null into the command run via start-process powershell... see below... Also, note at the end the finally "kill -force" kills the remaining child processes from the initial powershell.exe process-start... my program created childprocesses that keep running after the ctrl-c kill powershell.exe so i need to kill again...to kill the entire process tree.

$script:Proc             = $null

# Run Command as a separate process
function x1_process {
    
    write-host "`nx1_process: $args"
                
    $posh = (get-command powershell.exe).Source

    $iproc = Start-Process $posh -ArgumentList "`$null `| $args" -PassThru -NoNewWindow 
    $script:Proc = $iproc

    if ($iproc -eq $null) {
        throw "null proc"       
    }
    
    Wait-Process -InputObject $iproc

    $code = $iproc.ExitCode
    if ($code -ne 0) {
        throw "return-code:$code"
    }   
    
    write-host "ok`n"
    return
}

try {
    x1_process mycommand.exe arg1 arg2 ...
}
finally {
    if ($script:Proc) {
        if (-not $script:Proc.HasExited) {
            write-host -ForegroundColor Red "=> Killing X1_PROCESS <="
            Stop-Process -InputObject $script:Proc -Force -ErrorAction SilentlyContinue
        }
    }
}
  • Related