Skip to content

Commit 186d6be

Browse files
authored
Use NotifyEndApplication to re-enable VT mode (PowerShell#16612)
Use NotifyEndApplication to re-enable VT mode instead of doing it in InputLoop.Run, so that we run this code only after invoking native commands
1 parent 686c84c commit 186d6be

File tree

3 files changed

+40
-36
lines changed

3 files changed

+40
-36
lines changed

src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,18 +1071,16 @@ public override void NotifyBeginApplication()
10711071
{
10721072
lock (hostGlobalLock)
10731073
{
1074-
++_beginApplicationNotifyCount;
1075-
if (_beginApplicationNotifyCount == 1)
1074+
if (++_beginApplicationNotifyCount == 1)
10761075
{
1077-
// save the window title when first notified.
1078-
1076+
// Save the window title when first notified.
10791077
_savedWindowTitle = ui.RawUI.WindowTitle;
10801078
#if !UNIX
10811079
if (_initialConsoleMode != ConsoleControl.ConsoleModes.Unknown)
10821080
{
1083-
var activeScreenBufferHandle = ConsoleControl.GetActiveScreenBufferHandle();
1084-
_savedConsoleMode = ConsoleControl.GetMode(activeScreenBufferHandle);
1085-
ConsoleControl.SetMode(activeScreenBufferHandle, _initialConsoleMode);
1081+
var outputHandle = ConsoleControl.GetActiveScreenBufferHandle();
1082+
_savedConsoleMode = ConsoleControl.GetMode(outputHandle);
1083+
ConsoleControl.SetMode(outputHandle, _initialConsoleMode);
10861084
}
10871085
#endif
10881086
}
@@ -1097,17 +1095,26 @@ public override void NotifyEndApplication()
10971095
{
10981096
lock (hostGlobalLock)
10991097
{
1100-
Dbg.Assert(_beginApplicationNotifyCount > 0, "Not running an executable - NotifyBeginApplication was not called!");
1101-
--_beginApplicationNotifyCount;
1102-
if (_beginApplicationNotifyCount == 0)
1098+
if (--_beginApplicationNotifyCount == 0)
11031099
{
1104-
// restore the window title when the last application started has ended.
1105-
1100+
// Restore the window title when the last application started has ended.
11061101
ui.RawUI.WindowTitle = _savedWindowTitle;
11071102
#if !UNIX
11081103
if (_savedConsoleMode != ConsoleControl.ConsoleModes.Unknown)
11091104
{
11101105
ConsoleControl.SetMode(ConsoleControl.GetActiveScreenBufferHandle(), _savedConsoleMode);
1106+
if (_savedConsoleMode.HasFlag(ConsoleControl.ConsoleModes.VirtualTerminal))
1107+
{
1108+
// If the console output mode we just set already has 'VirtualTerminal' turned on,
1109+
// we don't need to try turn on the VT mode separately.
1110+
return;
1111+
}
1112+
}
1113+
1114+
if (ui.SupportsVirtualTerminal)
1115+
{
1116+
// Re-enable VT mode if it was previously enabled, as a native command may have turned it off.
1117+
ui.TryTurnOnVirtualTerminal();
11111118
}
11121119
#endif
11131120
}
@@ -2452,14 +2459,6 @@ internal void Run(bool inputLoopIsNested)
24522459

24532460
while (!_parent.ShouldEndSession && !_shouldExit)
24542461
{
2455-
#if !UNIX
2456-
if (ui.SupportsVirtualTerminal)
2457-
{
2458-
// need to re-enable VT mode if it was previously enabled as native commands may have turned it off
2459-
ui.TryTurnOnVtMode();
2460-
}
2461-
#endif
2462-
24632462
try
24642463
{
24652464
_parent._isRunningPromptLoop = true;

src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,28 +87,34 @@ internal ConsoleHostUserInterface(ConsoleHost parent)
8787

8888
if (SupportsVirtualTerminal)
8989
{
90-
SupportsVirtualTerminal = TryTurnOnVtMode();
90+
SupportsVirtualTerminal = TryTurnOnVirtualTerminal();
9191
}
9292
}
9393

94-
internal bool TryTurnOnVtMode()
94+
internal bool TryTurnOnVirtualTerminal()
9595
{
9696
#if UNIX
9797
return true;
9898
#else
9999
try
100100
{
101101
// Turn on virtual terminal if possible.
102-
103102
// This might throw - not sure how exactly (no console), but if it does, we shouldn't fail to start.
104-
var handle = ConsoleControl.GetActiveScreenBufferHandle();
105-
var m = ConsoleControl.GetMode(handle);
106-
if (ConsoleControl.NativeMethods.SetConsoleMode(handle.DangerousGetHandle(), (uint)(m | ConsoleControl.ConsoleModes.VirtualTerminal)))
103+
var outputHandle = ConsoleControl.GetActiveScreenBufferHandle();
104+
var outputMode = ConsoleControl.GetMode(outputHandle);
105+
106+
if (outputMode.HasFlag(ConsoleControl.ConsoleModes.VirtualTerminal))
107+
{
108+
return true;
109+
}
110+
111+
outputMode |= ConsoleControl.ConsoleModes.VirtualTerminal;
112+
if (ConsoleControl.NativeMethods.SetConsoleMode(outputHandle.DangerousGetHandle(), (uint)outputMode))
107113
{
108114
// We only know if vt100 is supported if the previous call actually set the new flag, older
109115
// systems ignore the setting.
110-
m = ConsoleControl.GetMode(handle);
111-
return (m & ConsoleControl.ConsoleModes.VirtualTerminal) != 0;
116+
outputMode = ConsoleControl.GetMode(outputHandle);
117+
return outputMode.HasFlag(ConsoleControl.ConsoleModes.VirtualTerminal);
112118
}
113119
}
114120
catch

src/System.Management.Automation/engine/NativeCommandProcessor.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -545,15 +545,14 @@ private void InitNativeProcess()
545545
Exception exceptionToRethrow = null;
546546
try
547547
{
548-
// If this process is being run standalone, tell the host, which might want
549-
// to save off the window title or other such state as might be tweaked by
550-
// the native process
548+
// Before start the executable, tell the host, which might want to save off the
549+
// window title or other such state as might be tweaked by the native process.
550+
Command.Context.EngineHostInterface.NotifyBeginApplication();
551+
_hasNotifiedBeginApplication = true;
552+
551553
if (_runStandAlone)
552554
{
553-
this.Command.Context.EngineHostInterface.NotifyBeginApplication();
554-
_hasNotifiedBeginApplication = true;
555-
556-
// Also, store the Raw UI coordinates so that we can scrape the screen after
555+
// Store the Raw UI coordinates so that we can scrape the screen after
557556
// if we are transcribing.
558557
if (_isTranscribing && (s_supportScreenScrape == true))
559558
{
@@ -1166,7 +1165,7 @@ private void CleanUp()
11661165
// We need to call 'NotifyEndApplication' as appropriate during cleanup
11671166
if (_hasNotifiedBeginApplication)
11681167
{
1169-
this.Command.Context.EngineHostInterface.NotifyEndApplication();
1168+
Command.Context.EngineHostInterface.NotifyEndApplication();
11701169
}
11711170

11721171
try

0 commit comments

Comments
 (0)