[Part 1: the following text is based on nppexec/issues/23 by LorneCash]
The problem #1: If you execute a PowerShell's script in NppExec's Console, the PowerShell process is not ended when the script is finished.
The solution #1: Use "cmd /c echo. | powershell" instead of "powershell" to emulate sending of the Enter key to PowerShell process.
The problem #2: PowerShell says: "File ... cannot be loaded because running scripts is disabled on this system".
The solution #2: Either use the command-line option "-ExecutionPolicy Unrestricted" (see the examples below) or set PowerShell's global ExecutionPolicy (see the second part of this article).
The problem #3: If a quoted file path is passed to the second instance of PowerShell, this second instance receives the file path without quotes.
The solution #3: Use escaped quotes \" \" instead of just " ".
Here is an example that illustrates this approach. Also it demonstrates how PowerShell's ExecutionPolicy can be applied to a single script. It is assumed that a .ps1 file is currently opened in Notepad++:
cmd /c echo. | PowerShell -ExecutionPolicy Unrestricted start-process PowerShell -ArgumentList '-ExecutionPolicy Unrestricted -File \"$(FULL_CURRENT_PATH)\"'
And here is an example of PowerShell's command executed in NppExec's Console:
cmd /c echo. | PowerShell -Command Write-Host 'Hello, World!'
Now let's consider the following scenario. When you are debugging PowerShell or batch scripts you usually run them a lot with pauses in them, so you end up with a lot of console windows that have to be closed manually. This can be automated by saving the PID (process id) of the last running process and then using this saved PID to close that process gracefully. Here is the corresponding NppExec's script that runs a PowerShell script file (.ps1) opened in Notepad++:
if "$(PS_ID)" != "" then // closing the previous running process by its id... cmd /C echo. | PowerShell -Command "get-process -Id $(PS_ID) -ErrorAction SilentlyContinue | ForEach-Object {$null = $_.CloseMainWindow()};" unset PS_ID endif // running a new process and saving its id... npe_console local v+ -- cmd /C echo. | PowerShell -ExecutionPolicy Unrestricted -Command "(start-process -PassThru PowerShell -ArgumentList '-File ""$(FULL_CURRENT_PATH)""').Id" set PS_ID = $(OUTPUT)
In case of a batch script file (.bat or .cmd), the NppExec's script will be slightly different:
if "$(PS_ID)" != "" then // closing the previous running process by its id... cmd /C echo. | PowerShell -Command "get-process -Id $(PS_ID) -ErrorAction SilentlyContinue | ForEach-Object {$null = $_.CloseMainWindow()};" unset PS_ID endif // running a new process and saving its id... npe_console local v+ -- cmd /C echo. | PowerShell -Command "(start-process -PassThru cmd -ArgumentList '/c ""$(FULL_CURRENT_PATH)""').Id" set PS_ID = $(OUTPUT)
Finally, we can merge these two NppExec's scripts into a new NppExec's script that will take care of both PowerShell and batch script files:
npp_console ? // don't show the Console if it's hidden npp_save // save the current file if "$(PS_ID)" != "" then // closing the previous running process by its id... cmd /C echo. | PowerShell -Command "get-process -Id $(PS_ID) -ErrorAction SilentlyContinue | ForEach-Object {$null = $_.CloseMainWindow()};" unset PS_ID endif // is it a batch file?.. set local IS_BATCH_FILE = false if "$(EXT_PART)" ~= ".bat" then set local IS_BATCH_FILE = true else if "$(EXT_PART)" ~= ".cmd" then set local IS_BATCH_FILE = true endif // running a new process and saving its id... npe_console local v+ -- if "$(IS_BATCH_FILE)" == "true" then cmd /C echo. | PowerShell -Command "(start-process -PassThru cmd -ArgumentList '/c ""$(FULL_CURRENT_PATH)""').Id" set PS_ID = $(OUTPUT) else if "$(EXT_PART)" ~= ".ps1" then cmd /C echo. | PowerShell -ExecutionPolicy Unrestricted -Command "(start-process -PassThru PowerShell -ArgumentList '-File ""$(FULL_CURRENT_PATH)""').Id" set PS_ID = $(OUTPUT) else messagebox "File type has not been configured in NppExec's 'Run' script" : "NppExec: Run - Unknown File Type" : warn endif
[Part 2: the text below was originally posted in NppExec's forum]
The problem: if you execute a PowerShell's script in NppExec's Console, the PowerShell process is not ended when the script is finished.
The solution: use "cmd /c echo. | powershell" instead of "powershell" to emulate sending of the Enter key to PowerShell process.
Here is an example of the full NppExec's script that uses the currently selected text as a PowerShell's program:
// path to PowerShell.exe set local PS_EXE = C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe // temporary file set local TEMP_FILE = $(SYS.TEMP)\ps_sel.ps1 // save selected text from current file to a temporary ANSI file SEL_SAVETO $(TEMP_FILE) :a // execute the temporary file in PowerShell and exit cmd /c echo. | "$(PS_EXE)" -nologo "$(TEMP_FILE)"
Note:
If PowerShell unexpectedly says something like
File "test.ps1" cannot be loaded because running scripts is disabled on this system
it could be related to the fact that there are 32-bit and 64-bit instances on 64-bit systems, and they can have different settings. According to https://stackoverflow.com/questions/4037939/powershell-says-execution-of-scripts-is-disabled-on-this-system
, the following should help:
x86 (32 bit) Open "C:\Windows\SysWOW64\cmd.exe" Run the command: "powershell Set-ExecutionPolicy RemoteSigned" x64 (64 bit) Open "C:\Windows\system32\cmd.exe" Run the command: "powershell Set-ExecutionPolicy RemoteSigned" You can check the bitness using - In CMD: echo %PROCESSOR_ARCHITECTURE% - In Powershell: [Environment]::Is64BitProcess
See also: Using cmd.exe [4.4].