Skip to content

Commit f7404b4

Browse files
committed
Create NativeCalls.cs
1 parent 8066dc9 commit f7404b4

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System;
2+
using System.Runtime.Versioning;
3+
using System.Runtime.InteropServices;
4+
using System.Diagnostics.CodeAnalysis;
5+
6+
7+
namespace Rephidock.CLI.RunWithColor;
8+
9+
10+
// Based on
11+
// https://stackoverflow.com/a/53391837
12+
13+
[SupportedOSPlatform("windows")]
14+
public static partial class NativeCalls {
15+
16+
#region //// Last Error
17+
18+
[LibraryImport("kernel32.dll")]
19+
private static partial uint GetLastError();
20+
21+
/// <summary>Returns result of GetLastError in kernel32.dll</summary>
22+
public static uint GetLastErrorCode() => GetLastErrorCode();
23+
24+
#endregion
25+
26+
#region //// Standard handles
27+
28+
public enum StdHandle : int {
29+
INVALID_HANDLE_VALUE = -1,
30+
31+
STD_INPUT_HANDLE = -10,
32+
STD_OUTPUT_HANDLE = -11,
33+
STD_ERROR_HANDLE = -12,
34+
}
35+
36+
[LibraryImport("kernel32.dll", SetLastError = true)]
37+
internal static partial IntPtr GetStdHandle(int nStdHandle); //returns Handle
38+
39+
#endregion
40+
41+
#region //// Console Mode
42+
43+
[SuppressMessage("Design", "CA1069:Enums values should not be duplicated", Justification = "Different use implies different name")]
44+
public enum ConsoleMode : uint {
45+
46+
ENABLE_EXTENDED_FLAGS = 0x0080,
47+
ENABLE_AUTO_POSITION = 0x100,
48+
49+
ENABLE_ECHO_INPUT = 0x0004,
50+
ENABLE_INSERT_MODE = 0x0020,
51+
ENABLE_LINE_INPUT = 0x0002,
52+
ENABLE_MOUSE_INPUT = 0x0010,
53+
ENABLE_PROCESSED_INPUT = 0x0001,
54+
ENABLE_QUICK_EDIT_MODE = 0x0040,
55+
ENABLE_WINDOW_INPUT = 0x0008,
56+
ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200,
57+
58+
//for screen buffer handle
59+
ENABLE_PROCESSED_OUTPUT = 0x0001,
60+
ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002,
61+
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004,
62+
DISABLE_NEWLINE_AUTO_RETURN = 0x0008,
63+
ENABLE_LVB_GRID_WORLDWIDE = 0x0010
64+
}
65+
66+
[LibraryImport("kernel32.dll", SetLastError = true)]
67+
[return: MarshalAs(UnmanagedType.Bool)]
68+
internal static partial bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
69+
70+
[LibraryImport("kernel32.dll", SetLastError = true)]
71+
[return: MarshalAs(UnmanagedType.Bool)]
72+
internal static partial bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
73+
74+
/// <summary>
75+
/// Enables or disables <see cref="ConsoleMode.ENABLE_VIRTUAL_TERMINAL_PROCESSING"/>
76+
/// and <see cref="ConsoleMode.DISABLE_NEWLINE_AUTO_RETURN"/> mode flags for
77+
/// the current console.
78+
/// </summary>
79+
/// <returns>True if operation succeeded, false otherwise</returns>
80+
public static bool SetVirtualTerminalOutput(bool enabled) {
81+
return SetConsoleMode(
82+
StdHandle.STD_OUTPUT_HANDLE,
83+
ConsoleMode.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ConsoleMode.DISABLE_NEWLINE_AUTO_RETURN,
84+
enabled: enabled
85+
);
86+
}
87+
88+
/// <summary>Sets console mode flags for the current console</summary>
89+
/// <returns>True if operation succeeded, false otherwise</returns>
90+
public static bool SetConsoleMode(StdHandle handle, ConsoleMode mode, bool enabled) {
91+
92+
// Get handle
93+
IntPtr stdHandle = GetStdHandle((int)handle);
94+
if (stdHandle == (IntPtr)StdHandle.INVALID_HANDLE_VALUE) {
95+
return false;
96+
}
97+
98+
// Get flags
99+
if (!GetConsoleMode(stdHandle, out uint consoleMode)) {
100+
return false;
101+
}
102+
103+
// Change flags
104+
if (enabled) {
105+
consoleMode |= (uint)mode;
106+
} else {
107+
consoleMode &= ~((uint)mode);
108+
}
109+
110+
// Set flags
111+
if (!SetConsoleMode(stdHandle, consoleMode)) {
112+
return false;
113+
}
114+
115+
return true;
116+
}
117+
118+
#endregion
119+
120+
}

0 commit comments

Comments
 (0)