1

Lets assume I have the following script:

$originalPath=pwd
D:\code\ps1\misc\title.ps1 "dynamo db"

$CURPATH = "$PSScriptRoot\path.txt"
$DB_DIR= cat $CURPATH

cd $DB_DIR
java -D"java.library.path=./DynamoDBLocal_lib" -jar DynamoDBLocal.jar
cd $originalPath

This script starts the java program correctly, however, when I hit CTRL+C, the last cd command is not executed.

Is this by design for powershell? Or can I change this?

deostroll
  • 11,661
  • 21
  • 90
  • 161

1 Answers1

2

This answer applies up to at least PowerShell (Core) 7.3.5.

When you use Ctrl-C to abort an external program, the current PowerShell script (runspace) is invariably terminated too.

While you cannot generally prevent your script from getting terminated,[1] you can perform clean-up actions, namely in the finally block of a try / catch / finally statement:

$originalPath = $PWD

# ...

try {

  cd $DB_DIR
  java -D"java.library.path=./DynamoDBLocal_lib" -jar DynamoDBLocal.jar

} finally {

  # This block is *always* executed, but limitations apply
  # if Ctrl-C was pressed:
  #  * Execution invariably ends with this block.
  #  * You cannot output to the success output stream or error stream,
  #    neither explicitly nor implicitly: doing so quietly and instantly
  #    aborts processing.
  #  * However, the *other* output streams *can* be targeted, namely with
  #    the following cmdlets (but note that except for Write-Host and Write-Warning, 
  #    producing visible output is opt-in):
  #     Write-Host, Write-Warning, Write-Verbose, Write-Debug, Write-Information

  cd $originalPath

}

Note the limitations with respect to what output streams you may target, described in the code comments above, which stem from the finally block executing late in the script-termination process.

Notably, attempts to use Write-Output or implicit success-stream output or Write-Error will quietly abort execution of the finally at that point, whereas Write-Host, Write-Verbose and Write-Warning, to name the most important ones, are safe to use.


[1] The only way to intercept Ctrl-C in order to prevent termination is via a custom keyboard-polling loop, after having set [Console]::TreatControlCAsInput = $false - see this answer for an example.

mklement0
  • 382,024
  • 64
  • 607
  • 775