This repository has been archived by the owner on Nov 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Program.cs
100 lines (77 loc) · 3.23 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Text;
using static Win32;
static class Program {
// Set buffer to 512K as temporal workaround of https://github.com/microsoft/WSL/issues/5063
public const int BufferSize = 512 * 1024;
static void Main() {
SetConsoleCP(65001);
SetConsoleOutputCP(65001);
var cmd = Environment.CommandLine;
// Extract command name
var arg = CommandLine.ExtractArg(cmd);
if(!(arg.length > 0))
return;
var command = CommandLine.ExtractCommandName(cmd, arg.start, arg.length);
if(!(command.length > 0))
return;
var builder = new StringBuilder(cmd.Length);
builder.Append("wsl.exe -e ");
builder.Append(cmd, command.start, command.length);
// Extract arguments and convert paths
while((arg = CommandLine.ExtractArg(cmd, arg.next)).next > 0) {
if(arg.length == 0)
continue;
builder.Append(' ');
if(arg.quot)
builder.Append('"');
if(!WslPath.PathToWsl(cmd, arg.start, arg.length, builder))
builder.Append(cmd, arg.start, arg.length);
if(arg.quot)
builder.Append('"');
}
PROCESS_INFORMATION proc;
// Check for interactive mode
if(Console.IsOutputRedirected) {
// Create pipe
var pipe = OpenPipe();
if(!pipe.ok)
throw new Exception("Failed to create pipe.");
// Do not inherit reading end of pipe
if(!SetHandleInformation(pipe.hRead, 1, 0))
throw new Exception("Failed to set up pipe.");
// Run WSL command
proc = CreateProcess(builder.ToString(), pipe.hWrite);
// Close own writing end of pipe to avoid ReadFile self locking
if(!CloseHandle(pipe.hWrite))
throw new Exception("Failed to close own writing handle.");
WslPath.ProcessOutput(pipe.hRead, GetStdHandle(-11));
} else {
// Run WSL command without processing
proc = CreateProcess(builder.ToString(), IntPtr.Zero);
}
WaitForSingleObject(proc.hProcess, -1);
GetExitCodeProcess(proc.hProcess, out var exitCode);
Environment.ExitCode = exitCode;
}
public unsafe static (bool ok, IntPtr hRead, IntPtr hWrite) OpenPipe() {
var secAttrs = new SECURITY_ATTRIBUTES {
nLength = sizeof(SECURITY_ATTRIBUTES),
bInheritHandle = true,
};
return (CreatePipe(out var hReadPipe, out var hWritePipe, secAttrs, BufferSize), hReadPipe, hWritePipe);
}
public unsafe static PROCESS_INFORMATION CreateProcess(string commandLine, IntPtr hWritePipe) {
var startupInfo = (hWritePipe == IntPtr.Zero) ? new STARTUPINFO() :
new STARTUPINFO {
cb = sizeof(STARTUPINFO),
hStdInput = GetStdHandle(-10),
hStdOutput = hWritePipe,
hStdError = GetStdHandle(-12),
dwFlags = 0x100,
};
if(!CreateProcessW(null, commandLine, null, null, true, 0, null, null, startupInfo, out var procInfo))
throw new Exception("Failed to launch WSL.");
return procInfo;
}
}