One day...
I'm a developer who usually uses Visual Studio IDE on Windows OS.
Recently, I registered the command for launching PowerShell console at [Tools] > [External Tools] menu in Visual Studio IDE, with the keyboard shortcut: Ctrl+P, Ctrl+S.
So I can open a PowerShell console rapidly, just entering two stroke keys, and the working directory is present in solution folder.
It works very fine and useful for me.
But, one day, I found the big problem...
I found that Ctrl + C is always ignored in the PowerShell console, which launched from Visual Studio IDE external tools menu.
For example, one of the scenario is this:
- I open the PowerShell console with Ctrl+P, Ctrl+S key combination from Visual Studio IDE.
- And I execute some long running console app, like "cordova run browser".
- After that, when I want to stop the running console app (in this case, "cordova" command), I press Ctrl + C usually.
But it doesn't work, never.
There is nothing to happen.
Ctrl + C is just ignored.
In the PowerShell console which is opened NOT from Visual Studio IDE, such as from start menu or from Windows Explorer menu or from "Run" box or etc., Ctrl + C is working very fine expectedly.
Pressing Ctrl + C keys can terminate a command when it is running.
Only the PowerShell which is a child process of Visual Studio IDE has the problem.
What's happening?
After for a long hour my investigation with internet searching, I found SetConsoleCtrlHandler Win32 API.
This Win32 API allows a Win32 process to customize the behavior of Ctrl + C key is pressed.
And, this is an important point, the document says the effect of changing this behavior inherits to the child process!
I guess, Visual Studio IDE (or any extensions live in it) calls SetConsoleCtrlHandler Win32 API to ignore to default behavior of Ctrl + C key pressing.
I think, therefor, the PowerShell console that is a child process of Visual Studio IDE is also ignoring the Ctrl + C.
How to resolve this issue?
After thinking for a while, I tried to solve this issue by calling SetConsoleCtrlHandler Win32 API in the PowerShell console in-process.
We can reset the behavior of Ctrl + C to system default with following code.
// C/C++ syntax with Win32 SDK
SetConsoleCtrlHandler(NULL, FALSE);
By the way, PowerShell can't invoke Win32 API directly.
Instead, I wrote a wrapper class library by C# which invokes SetConsoleCtrlHandler Win32 API, and build it to .NET assembly file (.dll).
PowerShell can load .NET assembly and invoke managed code in it.
Due to this mechanism, the PowerShell can invoke SetConsoleCtrlHandler Win32 API in that process via .NET assembly which I wrote.
I ran the following commands on a problem PowerShell console.
Add-Type -Path Path/To/MyWrapper.dll
[MyWrapperClass]::MyWrpperStaticMethodToEnableCtrlC()
After executed above commands, execute some long running console app such as "cordova run browser", and press Ctrl + C, then...
it could terminate the console app expectedly!
I didi it.
Conclusion
I published these works to GitHub, with wrapper class library assembly file (.dll).
GitHub - Ctrl + C Enabler for PowerShell (https://github.com/jsakamoto/CtrlCEnabler)
You can write PowerShell code that enables Ctrl + C default behavior into the $PROFILE file to apply enabling Ctrl + C whenever.
One more thing...
There is already great extension for Visual Studio IDE to launch PowerShell console: "Open Command Line" by Mads Kristensen.
The Ctrl + C works fine in the PowerShell console, which launched from this extension.
If you have a need to open a PowerShell console from Visual Studio IDE rapidly, in general cases, I recommend installing this extension.
Happy coding :)
Top comments (3)
Does CTRL+BREAK work?
I'm not sure because I have no keyboards that has break key.
Could you try to Ctrl + Break, and tell me does it work?
Thanks Mate