master
h 117 lines 3.22 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 WSLCProcessLauncher.h
8
9 Abstract:
10
11 Helper class to launch and wait for WSLC processes.
12 This is designed to function both for VM level and container level processes.
13 This class is also designed to work both from client & server side.
14
15 --*/
16
17 #pragma once
18 #include "HandleIO.h"
19 #include "wslc.h"
20 #include <variant>
21 #include <vector>
22 #include <string>
23
24 namespace wsl::windows::common {
25
26 class RunningWSLCProcess
27 {
28 public:
29 struct ProcessResult
30 {
31 int Code;
32 std::map<int, std::string> Output;
33 };
34
35 RunningWSLCProcess(WSLCProcessFlags Flags);
36 NON_COPYABLE(RunningWSLCProcess);
37 DEFAULT_MOVABLE(RunningWSLCProcess);
38
39 ProcessResult WaitAndCaptureOutput(DWORD TimeoutMs = INFINITE, std::vector<std::unique_ptr<io::OverlappedIOHandle>>&& ExtraHandles = {});
40 int Wait(DWORD TimeoutMs = INFINITE);
41 virtual io::HandleWrapper GetStdHandle(int Index) = 0;
42 virtual wil::unique_event GetExitEvent() = 0;
43 int GetExitCode();
44 WSLCProcessState State();
45
46 WSLCProcessFlags Flags() const;
47
48 protected:
49 virtual void GetState(WSLCProcessState* State, int* Code) = 0;
50
51 WSLCProcessFlags m_flags{};
52 };
53
54 class ClientRunningWSLCProcess : public RunningWSLCProcess
55 {
56 public:
57 NON_COPYABLE(ClientRunningWSLCProcess);
58 DEFAULT_MOVABLE(ClientRunningWSLCProcess);
59
60 ClientRunningWSLCProcess(wil::com_ptr<IWSLCProcess>&& process, WSLCProcessFlags Flags);
61 io::HandleWrapper GetStdHandle(int Index) override;
62 wil::unique_event GetExitEvent() override;
63 IWSLCProcess& Get();
64
65 protected:
66 void GetState(WSLCProcessState* State, int* Code) override;
67
68 private:
69 wil::com_ptr<IWSLCProcess> m_process;
70 };
71 class WSLCProcessLauncher
72 {
73 public:
74 NON_COPYABLE(WSLCProcessLauncher);
75 NON_MOVABLE(WSLCProcessLauncher);
76
77 WSLCProcessLauncher(
78 const std::string& Executable,
79 const std::vector<std::string>& Arguments,
80 const std::vector<std::string>& Environment = {},
81 WSLCProcessFlags = WSLCProcessFlagsNone);
82
83 void SetTtySize(ULONG Rows, ULONG Columns);
84 void SetWorkingDirectory(std::string&& WorkingDirectory);
85 void SetUser(std::string&& User);
86 void SetDetachKeys(std::string&& DetachKeys);
87
88 std::tuple<HRESULT, std::optional<ClientRunningWSLCProcess>, int> LaunchNoThrow(IWSLCSession& Session);
89 std::tuple<HRESULT, std::optional<ClientRunningWSLCProcess>> LaunchNoThrow(IWSLCContainer& Container);
90
91 template <typename T>
92 auto Launch(T& Context)
93 {
94 auto result = LaunchNoThrow(Context);
95 THROW_IF_FAILED(std::get<0>(result));
96
97 return std::move(std::get<1>(result).value());
98 }
99
100 std::string FormatResult(const RunningWSLCProcess::ProcessResult& result);
101 std::string FormatResult(const int code);
102
103 protected:
104 std::tuple<WSLCProcessOptions, std::vector<const char*>, std::vector<const char*>> CreateProcessOptions();
105
106 WSLCProcessFlags m_flags{};
107 std::string m_executable;
108 std::string m_workingDirectory;
109 std::string m_user;
110 std::optional<std::string> m_detachKeys;
111 std::vector<std::string> m_arguments;
112 std::vector<std::string> m_environment;
113 DWORD m_rows = 24;
114 DWORD m_columns = 80;
115 };
116
117 } // namespace wsl::windows::common