Create alias to wslc.exe (#40556)

David Bennett committed May 15, 2026 at 12:03 UTC 10dca9a9dd2fbe5c4b7aef550610a3e8b02a7141
2 files changed +73
msipackage/package.wix.in
+1
@@ -28,6 +28,7 @@
28
29 <File Id="wslg.exe" Name="wslg.exe" Source="${PACKAGE_INPUT_DIR}/wslg.exe" />
30 <File Id="wslc.exe" Name="wslc.exe" Source="${PACKAGE_INPUT_DIR}/wslc.exe" />
31 + <File Id="container.exe" Name="container.exe" Source="${PACKAGE_INPUT_DIR}/wslc.exe" />
32 <File Id="wslhost.exe" Name="wslhost.exe" Source="${PACKAGE_INPUT_DIR}/wslhost.exe" />
33 <File Id="wslrelay.exe" Name="wslrelay.exe" Source="${PACKAGE_INPUT_DIR}/wslrelay.exe" />
34 <File Id="wslserviceproxystub.dll" Name="wslserviceproxystub.dll" Source="${PACKAGE_INPUT_DIR}/wslserviceproxystub.dll" />
test/windows/wslc/e2e/WSLCE2EAliasTests.cpp new
+72
@@ -0,0 +1,72 @@
1 +/*++
2 +
3 +Copyright (c) Microsoft. All rights reserved.
4 +
5 +Module Name:
6 +
7 + WSLCE2EAliasTests.cpp
8 +
9 +Abstract:
10 +
11 + This file contains end-to-end tests for verifying the command alias functionality.
12 +--*/
13 +
14 +#include "precomp.h"
15 +#include "windows/Common.h"
16 +#include "WSLCExecutor.h"
17 +
18 +namespace WSLCE2ETests {
19 +
20 +namespace {
21 +
22 + inline std::wstring GetContainerExePath()
23 + {
24 + return (std::filesystem::path(wsl::windows::common::wslutil::GetMsiPackagePath().value()) / L"container.exe").wstring();
25 + }
26 +
27 + WSLCExecutionResult RunContainerExe(const std::wstring& commandLine)
28 + {
29 + auto cmd = L"\"" + GetContainerExePath() + L"\" " + commandLine;
30 + wsl::windows::common::SubProcess process(nullptr, cmd.c_str());
31 + const auto output = process.RunAndCaptureOutput();
32 + return {.CommandLine = commandLine, .Stdout = output.Stdout, .Stderr = output.Stderr, .ExitCode = output.ExitCode};
33 + }
34 +
35 +} // namespace
36 +
37 +class WSLCE2EAliasTests
38 +{
39 + WSLC_TEST_CLASS(WSLCE2EAliasTests)
40 +
41 + TEST_CLASS_SETUP(TestClassSetup)
42 + {
43 + return true;
44 + }
45 +
46 + TEST_CLASS_CLEANUP(TestClassCleanup)
47 + {
48 + return true;
49 + }
50 +
51 + // Verify that container.exe exists on disk as the deployed alias for wslc.exe.
52 + WSLC_TEST_METHOD(WSLCE2E_ContainerExe_IsDeployed)
53 + {
54 + const auto containerExePath = GetContainerExePath();
55 + VERIFY_IS_TRUE(std::filesystem::exists(containerExePath), (L"container.exe not found at: " + containerExePath).c_str());
56 + }
57 +
58 + // Verify that container.exe responds to --help identically to wslc.exe,
59 + // confirming it is a functional alias and not just a placeholder.
60 + WSLC_TEST_METHOD(WSLCE2E_ContainerExe_HelpCommand_MatchesWslc)
61 + {
62 + const auto wslcResult = RunWslc(L"--help");
63 + wslcResult.Verify({.Stderr = L"", .ExitCode = 0});
64 +
65 + const auto containerResult = RunContainerExe(L"--help");
66 + containerResult.Verify({.Stderr = L"", .ExitCode = 0});
67 +
68 + VERIFY_ARE_EQUAL(wslcResult.Stdout.value(), containerResult.Stdout.value());
69 + }
70 +};
71 +
72 +} // namespace WSLCE2ETests