diff --git a/src/AppInstallerCLICore/Commands/RootCommand.cpp b/src/AppInstallerCLICore/Commands/RootCommand.cpp index 255f3ae807..a385fbcd4b 100644 --- a/src/AppInstallerCLICore/Commands/RootCommand.cpp +++ b/src/AppInstallerCLICore/Commands/RootCommand.cpp @@ -126,6 +126,35 @@ namespace AppInstaller::CLI } adminSettingsTable.Complete(); } + + void OutputKeyDirectories(Execution::Context& context) + { + Execution::TableOutput<2> keyDirectories{ context.Reporter, { Resource::String::KeyDirectoriesHeader, {} } }; + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::Logs }, Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation, true).u8string() }); + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::UserSettings }, UserSettings::SettingsFilePath(true).u8string() }); + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableLinksUser }, Runtime::GetPathTo(Runtime::PathName::PortableLinksUserLocation, true).u8string() }); + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableLinksMachine }, Runtime::GetPathTo(Runtime::PathName::PortableLinksMachineLocation, true).u8string() }); + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRootUser }, Runtime::GetPathTo(Runtime::PathName::PortablePackageUserRoot, true).u8string() }); + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRoot86 }, Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRootX86, true).u8string() }); + if (Utility::GetSystemArchitecture() == Utility::Architecture::X64 || Utility::GetSystemArchitecture() == Utility::Architecture::Arm64) + { + keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRoot64 }, Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRootX64, true).u8string() }); + } + keyDirectories.Complete(); + context.Reporter.Info() << std::endl; + } + + void OutputLinks(Execution::Context& context) + { + Execution::TableOutput<2> links{ context.Reporter, { Resource::String::Links, {} } }; + links.OutputLine({ Resource::LocString{ Resource::String::PrivacyStatement }, "https://aka.ms/winget-privacy" }); + links.OutputLine({ Resource::LocString{ Resource::String::LicenseAgreement }, "https://aka.ms/winget-license" }); + links.OutputLine({ Resource::LocString{ Resource::String::ThirdPartSoftwareNotices }, "https://aka.ms/winget-3rdPartyNotice" }); + links.OutputLine({ Resource::LocString{ Resource::String::MainHomepage }, "https://aka.ms/winget" }); + links.OutputLine({ Resource::LocString{ Resource::String::WindowsStoreTerms }, "https://www.microsoft.com/en-us/storedocs/terms-of-sale" }); + links.Complete(); + context.Reporter.Info() << std::endl; + } } std::vector> RootCommand::GetCommands() const @@ -211,22 +240,10 @@ namespace AppInstaller::CLI info << Resource::String::Package(Runtime::GetPackageVersion()) << std::endl; }; - info << std::endl << Resource::String::Logs(Utility::LocIndView{ Runtime::GetPathTo(Runtime::PathName::DefaultLogLocationForDisplay).u8string() }) << std::endl; - info << std::endl << Resource::String::UserSettings(Utility::LocIndView{ UserSettings::SettingsFilePath(true).u8string() }) << std::endl; - - info << std::endl; - - Execution::TableOutput<2> links{ context.Reporter, { Resource::String::Links, {} } }; - - links.OutputLine({ Resource::LocString(Resource::String::PrivacyStatement).get(), "https://aka.ms/winget-privacy" }); - links.OutputLine({ Resource::LocString(Resource::String::LicenseAgreement).get(), "https://aka.ms/winget-license" }); - links.OutputLine({ Resource::LocString(Resource::String::ThirdPartSoftwareNotices).get(), "https://aka.ms/winget-3rdPartyNotice" }); - links.OutputLine({ Resource::LocString(Resource::String::MainHomepage).get(), "https://aka.ms/winget" }); - links.OutputLine({ Resource::LocString(Resource::String::WindowsStoreTerms).get(), "https://www.microsoft.com/en-us/storedocs/terms-of-sale" }); - - links.Complete(); info << std::endl; + OutputKeyDirectories(context); + OutputLinks(context); OutputGroupPolicies(context); OutputAdminSettings(context); } diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h index bff7ff6f76..945d573406 100644 --- a/src/AppInstallerCLICore/Resources.h +++ b/src/AppInstallerCLICore/Resources.h @@ -219,6 +219,7 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(InvalidJsonFile); WINGET_DEFINE_RESOURCE_STRINGID(InvalidNameError); WINGET_DEFINE_RESOURCE_STRINGID(InvalidPathToNestedInstaller); + WINGET_DEFINE_RESOURCE_STRINGID(KeyDirectoriesHeader); WINGET_DEFINE_RESOURCE_STRINGID(LicenseAgreement); WINGET_DEFINE_RESOURCE_STRINGID(Links); WINGET_DEFINE_RESOURCE_STRINGID(ListCommandLongDescription); @@ -312,8 +313,13 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(PortableHashMismatchOverrideRequired); WINGET_DEFINE_RESOURCE_STRINGID(PortableAliasAdded); WINGET_DEFINE_RESOURCE_STRINGID(PortableInstallFailed); + WINGET_DEFINE_RESOURCE_STRINGID(PortableLinksMachine); + WINGET_DEFINE_RESOURCE_STRINGID(PortableLinksUser); WINGET_DEFINE_RESOURCE_STRINGID(PortablePackageAlreadyExists); WINGET_DEFINE_RESOURCE_STRINGID(PortableRegistryCollisionOverridden); + WINGET_DEFINE_RESOURCE_STRINGID(PortableRoot64); + WINGET_DEFINE_RESOURCE_STRINGID(PortableRoot86); + WINGET_DEFINE_RESOURCE_STRINGID(PortableRootUser); WINGET_DEFINE_RESOURCE_STRINGID(PositionArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(PreserveArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(PressEnterToContinue); diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index 24775cb6b1..e17431b031 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -319,6 +319,10 @@ They can be configured through the settings file 'winget settings'. Argument name was not recognized for the current command: '{0}' {Locked="{0}"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example'). + + Winget Directories + Header for a table detailing the directories Winget uses for key operations like logging and portable installs + Locale to use (BCP47 format) {Locked="BCP47"} @@ -775,8 +779,8 @@ They can be configured through the settings file 'winget settings'. Both local manifest and search query arguments are provided - Logs: {0} - {Locked="{0}"} Label displayed for diagnostic files containing information about the application use. {0} is a placeholder replaced by the logs directory path. + Logs + Label displayed for diagnostic files containing information about the application use. The installer is blocked by policy @@ -1402,6 +1406,21 @@ Please specify one of them using the --source option to proceed. Command line alias added: + + Portable Links Directory (Machine) + + + Portable Links Directory (User) + + + Portable Package Root (User) + + + Portable Package Root (x86) + + + Portable Package Root (x64) + Portable install failed; Cleaning up... @@ -1580,8 +1599,8 @@ Please specify one of them using the --source option to proceed. Export settings - User Settings: {0} - {Locked="{0}"} Label displayed for the file containing the user settings. {0} is a placeholder replaced by the user settings file path. + User Settings + Label displayed for the file containing the user settings. Settings file couldn't load. Using default values. diff --git a/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h b/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h index 8683b567ad..0031b4febf 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h @@ -39,8 +39,6 @@ namespace AppInstaller::Runtime LocalState, // The default location where log files are located. DefaultLogLocation, - // The default location, anonymized using environment variables. - DefaultLogLocationForDisplay, // The location that standard type settings are stored. // In a packaged context, this returns a prepend value for the container name. StandardSettings, @@ -112,10 +110,10 @@ namespace AppInstaller::Runtime // Gets the PathDetails used for the given path. // This is exposed primarily to allow for testing, GetPathTo should be preferred. - PathDetails GetPathDetailsFor(PathName path); + PathDetails GetPathDetailsFor(PathName path, bool forDisplay = false); // Gets the path to the requested location. - std::filesystem::path GetPathTo(PathName path); + std::filesystem::path GetPathTo(PathName path, bool forDisplay = false); // Gets a new temp file path. std::filesystem::path GetNewTempFilePath(); diff --git a/src/AppInstallerCommonCore/Runtime.cpp b/src/AppInstallerCommonCore/Runtime.cpp index 2347c719c6..55a5d9b905 100644 --- a/src/AppInstallerCommonCore/Runtime.cpp +++ b/src/AppInstallerCommonCore/Runtime.cpp @@ -485,7 +485,7 @@ namespace AppInstaller::Runtime } #ifndef WINGET_DISABLE_FOR_FUZZING - PathDetails GetPathDetailsForPackagedContext(PathName path) + PathDetails GetPathDetailsForPackagedContext(PathName path, bool forDisplay = false) { PathDetails result; @@ -504,12 +504,10 @@ namespace AppInstaller::Runtime result.Path.assign(appStorage.LocalFolder().Path().c_str()); break; case PathName::DefaultLogLocation: - case PathName::DefaultLogLocationForDisplay: // To enable UIF collection through Feedback hub, we must put our logs here. result.Path.assign(appStorage.LocalFolder().Path().c_str()); result.Path /= WINGET_DEFAULT_LOG_DIRECTORY; - - if (path == PathName::DefaultLogLocationForDisplay) + if (forDisplay) { ReplaceCommonPathPrefix(result.Path, GetKnownFolderPath(FOLDERID_LocalAppData), "%LOCALAPPDATA%"); } @@ -536,13 +534,19 @@ namespace AppInstaller::Runtime } break; case PathName::UserProfile: - case PathName::PortablePackageUserRoot: case PathName::PortablePackageMachineRootX64: case PathName::PortablePackageMachineRootX86: - case PathName::PortableLinksUserLocation: case PathName::PortableLinksMachineLocation: result = GetPathDetailsCommon(path); break; + case PathName::PortableLinksUserLocation: + case PathName::PortablePackageUserRoot: + result = GetPathDetailsCommon(path); + if (forDisplay) + { + ReplaceCommonPathPrefix(result.Path, GetKnownFolderPath(FOLDERID_LocalAppData), "%LOCALAPPDATA%"); + } + break; case PathName::SelfPackageRoot: result.Path = GetPackagePath(); result.Create = false; @@ -555,7 +559,7 @@ namespace AppInstaller::Runtime } #endif - PathDetails GetPathDetailsForUnpackagedContext(PathName path) + PathDetails GetPathDetailsForUnpackagedContext(PathName path, bool forDisplay = false) { PathDetails result; @@ -564,7 +568,16 @@ namespace AppInstaller::Runtime case PathName::Temp: case PathName::DefaultLogLocation: { - result.Path = GetPathToUserTemp(); + if (forDisplay) + { + result.Path.assign("%TEMP%"); + result.Create = false; + } + else + { + result.Path = GetPathToUserTemp(); + } + result.Path /= s_DefaultTempDirectory; result.Path /= GetRuntimePathStateName(); if (path == PathName::Temp) @@ -575,12 +588,6 @@ namespace AppInstaller::Runtime } } break; - case PathName::DefaultLogLocationForDisplay: - result.Path.assign("%TEMP%"); - result.Path /= s_DefaultTempDirectory; - result.Path /= GetRuntimePathStateName(); - result.Create = false; - break; case PathName::LocalState: result.Path = GetPathToAppDataDir(s_AppDataDir_State); result.Path /= GetRuntimePathStateName(); @@ -629,14 +636,14 @@ namespace AppInstaller::Runtime return result; } - PathDetails GetPathDetailsFor(PathName path) + PathDetails GetPathDetailsFor(PathName path, bool forDisplay) { PathDetails result; #ifndef WINGET_DISABLE_FOR_FUZZING if (IsRunningInPackagedContext()) { - result = GetPathDetailsForPackagedContext(path); + result = GetPathDetailsForPackagedContext(path, forDisplay); } else #endif @@ -656,9 +663,9 @@ namespace AppInstaller::Runtime return result; } - std::filesystem::path GetPathTo(PathName path) + std::filesystem::path GetPathTo(PathName path, bool forDisplay) { - PathDetails details = GetPathDetailsFor(path); + PathDetails details = GetPathDetailsFor(path, forDisplay); if (details.Create) {