Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide console only if it's dedicated to the launcher process #184

Merged
merged 12 commits into from
May 3, 2022
Merged
4 changes: 2 additions & 2 deletions DistroLauncher-Appx/MyDistro.appxmanifest
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Identity Name="CanonicalGroupLimited.UbuntuDev.AppID.Dev" Version="4.10.42.0" Publisher="CN=23596F84-C3EA-4CD8-A7DF-550DCE37BCD0" ProcessorArchitecture="x64" />
<mp:PhoneIdentity PhoneProductId="160867c6-4e75-4e36-85c6-1543de07d5f3" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
Expand All @@ -18,7 +18,7 @@
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="UbuntuDev.LauncherName.Dev" Executable="UbuntuDev.LauncherName.Dev.exe" EntryPoint="Windows.FullTrustApplication">
<Application Id="UbuntuDev.LauncherName.Dev" Executable="UbuntuDev.LauncherName.Dev.exe" EntryPoint="Windows.FullTrustApplication" uap10:Parameters="--hide-console">
<uap:VisualElements DisplayName="UbuntuDev.FullName.Dev" Description="UbuntuDev.FullName.Dev on Windows" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
</uap:DefaultTile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,39 @@ namespace Oobe::internal
ASSERT_TRUE(std::holds_alternative<InstallDefault>(opts));
}

// Tests the ManifestMatchedInstall and combinations with it.
TEST(ExtendedCliParserTests, StoreStartMenuInvocation)
{
std::vector<std::wstring_view> args{ARG_EXT_UAP10_PARAMETERS};
auto opts = parseExtendedOptions(args);
ASSERT_TRUE(std::holds_alternative<ManifestMatchedInstall>(opts));
ASSERT_TRUE(args.empty());
}

TEST(ExtendedCliParserTests, InvalidCombinationWithManifestMatched1)
{
std::vector<std::wstring_view> args{L"install", ARG_EXT_UAP10_PARAMETERS};
auto opts = parseExtendedOptions(args);
ASSERT_TRUE(std::holds_alternative<std::monostate>(opts));
ASSERT_EQ(args.size(), 1);
}

TEST(ExtendedCliParserTests, InvalidCombinationWithManifestMatched2)
{
std::vector<std::wstring_view> args{L"install", ARG_EXT_INSTALLER_GUI, ARG_EXT_UAP10_PARAMETERS};
auto opts = parseExtendedOptions(args);
ASSERT_TRUE(std::holds_alternative<std::monostate>(opts));
ASSERT_EQ(args.size(), 1);
}

TEST(ExtendedCliParserTests, InvalidCombinationWithManifestMatched3)
{
std::vector<std::wstring_view> args{L"config", ARG_EXT_UAP10_PARAMETERS};
auto opts = parseExtendedOptions(args);
ASSERT_TRUE(std::holds_alternative<std::monostate>(opts));
ASSERT_EQ(args.size(), 1);
}

// Tests whether the upstream options remain preserved:
TEST(ExtendedCliParserTests, InstallRootIsUpstream)
{
Expand Down
8 changes: 7 additions & 1 deletion DistroLauncher/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ namespace Oobe
return std::holds_alternative<internal::Reconfig>(arg);
}

bool canHideConsole() const
{
return std::holds_alternative<internal::ManifestMatchedInstall>(arg);
}

public:
/// Returns true if the command line parsing doesn't require running the OOBE.
/// That implies partial command line parsing, with the required actions deferred to the upstream code.
Expand Down Expand Up @@ -65,6 +70,7 @@ namespace Oobe
HRESULT hr =
std::visit(internal::overloaded{
[&](AutoInstall& option) { return impl_.do_autoinstall(option.autoInstallFile); },
[&](ManifestMatchedInstall& option) { return impl_.do_install(Mode::AutoDetect); },
[&](InstallDefault& option) { return impl_.do_install(Mode::AutoDetect); },
[&](InstallOnlyDefault& option) { return impl_.do_install(Mode::AutoDetect); },
[&](InteractiveInstallOnly<OobeGui>& option) { return impl_.do_install(Mode::Gui); },
Expand Down Expand Up @@ -104,7 +110,7 @@ namespace Oobe
if (isAutoInstall() || shouldSkipInstaller()) {
return;
}
impl_.do_run_splash();
impl_.do_run_splash(canHideConsole());
}
};
}
14 changes: 8 additions & 6 deletions DistroLauncher/ApplicationStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace Oobe
SplashEnabledStrategy::SplashEnabledStrategy() : splashExePath{splashPath()}
{ }

void SplashEnabledStrategy::do_run_splash()
void SplashEnabledStrategy::do_run_splash(bool hideConsole)
{
if (!std::filesystem::exists(splashExePath)) {
wprintf(L"Splash executable [%s] not found.\n", splashExePath.c_str());
Expand Down Expand Up @@ -142,8 +142,9 @@ namespace Oobe
return;
}
splashWindow = std::get<SplashController<>::States::Visible>(transition.value()).window;
console.value().hideConsoleWindow();
consoleIsVisible = false;
if (hideConsole) {
consoleIsVisible = !console.value().hideConsoleWindow();
}
splashIsRunning = true;
}

Expand All @@ -154,7 +155,7 @@ namespace Oobe

void SplashEnabledStrategy::do_show_console()
{
if (consoleIsVisible) {
if (!console.has_value()) {
return;
}
std::unique_lock<std::timed_mutex> guard{consoleGuard, std::defer_lock};
Expand All @@ -169,8 +170,9 @@ namespace Oobe
if (splashWindow.has_value()) {
topWindow = splashWindow.value();
}
console.value().showConsoleWindow(topWindow);
consoleIsVisible = true;
if (!consoleIsVisible) {
consoleIsVisible = console.value().showConsoleWindow(topWindow);
}
}

void SplashEnabledStrategy::do_close_splash()
Expand Down
4 changes: 2 additions & 2 deletions DistroLauncher/ApplicationStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace Oobe
HRESULT do_reconfigure();

/// Triggers the console redirection and launch the splash screen application.
void do_run_splash();
void do_run_splash(bool hideConsole = false);

SplashEnabledStrategy();
~SplashEnabledStrategy() = default;
Expand All @@ -100,7 +100,7 @@ namespace Oobe

/// Prints to the console an error message informing that this platform doesn't support running the splash
/// screen.
void do_run_splash()
void do_run_splash(bool hideConsole = false)
{
wprintf(L"This device architecture doesn't support running the splash screen.\n");
}
Expand Down
7 changes: 5 additions & 2 deletions DistroLauncher/console_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,12 @@ namespace Win32Utils

bool showConsoleWindow(HWND topWindow) const
{
if (auto res = Win32Utils::resize_to(window_, topWindow); res != 0) {
Helpers::PrintErrorMessage(HRESULT_FROM_WIN32(res));
if (IsWindowVisible(topWindow) == TRUE) {
if (auto res = Win32Utils::resize_to(window_, topWindow); res != 0) {
Helpers::PrintErrorMessage(HRESULT_FROM_WIN32(res));
}
}

// If the window was previously visible, the return value is nonzero.
// If the window was previously hidden, the return value is zero.
return ShowWindow(window_, SW_SHOWNORMAL) == FALSE;
Expand Down
18 changes: 16 additions & 2 deletions DistroLauncher/extended_cli_parser.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Canonical Ltd
* Copyright (C) 2022 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
Expand Down Expand Up @@ -54,6 +54,11 @@ namespace Oobe::internal

Opts parse(const std::vector<std::wstring_view>& arguments)
{
// launcher.exe --hide-console - Windows Shell GUI invocation as declared in the appxmanifest. Hides the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mismatch: the option is named --from-start-menu-or-store.

TBH, I prefer hide-console which is what the option will do instead of basing on a policy based on where it starts from (and which can evolve)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the original idea, I changed my mind due the fact that later we may want to do other things besides hidding the console, but I guess you're right. I'm reverting to --hide-console.

// console, runs the OOBE (auto detect graphics support) and brings the shell at the end.
if (auto result = tryParse<ManifestMatchedInstall>(arguments); result.has_value()) {
return result.value();
}
// launcher.exe - Runs the OOBE (auto detect graphics support) and brings the shell at the end.
if (auto result = tryParse<InstallDefault>(arguments); result.has_value()) {
return result.value();
Expand Down Expand Up @@ -110,11 +115,20 @@ namespace Oobe::internal
Opts parseExtendedOptions(std::vector<std::wstring_view>& arguments)
{
Opts options{parse(arguments)};

// Erasing the extended command line options to avoid confusion in the upstream code.
auto it = std::remove_if(arguments.begin(), arguments.end(), [](auto arg) {
return std::find(allExtendedArgs.begin(), allExtendedArgs.end(), arg) != allExtendedArgs.end();
});
arguments.erase(it, arguments.end());

#ifdef UNSUPPORTED_EXTENDED_CLI
if (shouldWarnUnsupported(options)) {
wprintf(L"Warning: ignoring command line options invalid for this Ubuntu release.\n");
}
return {};
#else
return options;
#endif // UNSUPPORTED_EXTENDED_CLI
}
}
}
39 changes: 33 additions & 6 deletions DistroLauncher/extended_cli_parser.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Canonical Ltd
* Copyright (C) 2022 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
Expand All @@ -20,11 +20,12 @@
#define ARG_EXT_INSTALLER_TUI ARG_EXT_ENABLE_INSTALLER L"tui"
#define ARG_EXT_DISABLE_INSTALLER ARG_EXT_ENABLE_INSTALLER L"none"
#define ARG_EXT_AUTOINSTALL L"--autoinstall"
#define ARG_EXT_UAP10_PARAMETERS L"--hide-console"

namespace Oobe::internal
{
static constexpr std::array allExtendedArgs{ARG_EXT_AUTOINSTALL, ARG_EXT_DISABLE_INSTALLER, ARG_EXT_INSTALLER_GUI,
ARG_EXT_INSTALLER_TUI};
ARG_EXT_INSTALLER_TUI, ARG_EXT_UAP10_PARAMETERS};
// compile-time array concatenation.
template <typename T, std::size_t SizeA, std::size_t SizeB>
constexpr std::array<T, SizeA + SizeB> join(const std::array<T, SizeA>& a, const std::array<T, SizeB>& b)
Expand Down Expand Up @@ -56,6 +57,10 @@ namespace Oobe::internal
{
static constexpr std::array<std::wstring_view, 1> requirements{ARG_EXT_INSTALLER_TUI};
};
struct ManifestMatchedInstall // matches the invocation declared in the .appxmanifest.
{
static constexpr std::array<std::wstring_view, 1> requirements{ARG_EXT_UAP10_PARAMETERS};
};
struct InstallDefault
{
static constexpr std::array<std::wstring_view, 0> requirements{};
Expand All @@ -79,13 +84,35 @@ namespace Oobe::internal

// InteractiveInstallOnly<SkipInstaller> and InteractiveInstallShell<SkipInstaller> are actually std::monostate,
// i.e. both go to upstream resolution.
using Opts = std::variant<std::monostate, AutoInstall, InstallDefault, InstallOnlyDefault,
InteractiveInstallOnly<OobeGui>, InteractiveInstallOnly<OobeTui>,
InteractiveInstallShell<OobeGui>, InteractiveInstallShell<OobeTui>, Reconfig>;

// clang-format off
// [clang-format appears to have trouble with long declarations like the following.]
using Opts = std::variant<std::monostate, // The upstream command line parsing effects.
AutoInstall,
ManifestMatchedInstall,
InstallDefault,
InstallOnlyDefault,
InteractiveInstallOnly<OobeGui>,
InteractiveInstallOnly<OobeTui>,
InteractiveInstallShell<OobeGui>,
InteractiveInstallShell<OobeTui>,
Reconfig>;
// clang-format on
/// Parses a vector of command line arguments according to the extended command line options declared above. The
/// extended options are removed from the original vector as a side effect to avoid confusing the "upstream command
/// line parsing" routines. Notice that argv[0], i.e. the program name, is presumed not to be part of the arguments
/// vector. See DistroLauncher.cpp main() function.
Opts parseExtendedOptions(std::vector<std::wstring_view>& arguments);

/// Returns true if the command line parsing result is invalid for the case when the extended CLI is unsupported
/// (the case for older releases).
inline bool shouldWarnUnsupported(const Opts& options)
{
// [ARG_EXT_UAP10_PARAMETERS] must be accepted in the old releases, even though it will be jsut discarded,
// thus we should not warn for this case. The same stands for the empty CLI case.
bool noWarnIf = std::holds_alternative<ManifestMatchedInstall>(options) ||
std::holds_alternative<InstallDefault>(options) ||
std::holds_alternative<std::monostate>(options);

return !noWarnIf;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Identity Name="CanonicalGroupLimited.Ubuntu" Version="2004.4.42.0" Publisher="CN=23596F84-C3EA-4CD8-A7DF-550DCE37BCD0" ProcessorArchitecture="x64" />
<mp:PhoneIdentity PhoneProductId="160867c6-4e75-4e36-85c6-1543de07d5f3" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
Expand All @@ -18,7 +18,7 @@
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="ubuntu" Executable="ubuntu.exe" EntryPoint="Windows.FullTrustApplication">
<Application Id="ubuntu" Executable="ubuntu.exe" EntryPoint="Windows.FullTrustApplication" uap10:Parameters="--hide-console">
<uap:VisualElements DisplayName="Ubuntu" Description="Ubuntu on Windows" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
</uap:DefaultTile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp uap2 uap3 rescap desktop">
<Identity Name="CanonicalGroupLimited.Ubuntu18.04LTS" Version="1804.5.42.0" Publisher="CN=23596F84-C3EA-4CD8-A7DF-550DCE37BCD0" ProcessorArchitecture="x64" />
<mp:PhoneIdentity PhoneProductId="160867c6-4e75-4e36-85c6-1543de07d5f3" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
Expand All @@ -18,7 +18,7 @@
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="ubuntu1804" Executable="ubuntu1804.exe" EntryPoint="Windows.FullTrustApplication">
<Application Id="ubuntu1804" Executable="ubuntu1804.exe" EntryPoint="Windows.FullTrustApplication" uap10:Parameters="--hide-console">
<uap:VisualElements DisplayName="Ubuntu 18.04.5 LTS" Description="Ubuntu 18.04.5 LTS on Windows" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
</uap:DefaultTile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#pragma once
#pragma once
#define UNSUPPORTED_EXTENDED_CLI
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#pragma once
#pragma once
#define UNSUPPORTED_EXTENDED_CLI
Loading