Argument.cpp (36373B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "Argument.h" 5 #include "Command.h" 6 #include "Resources.h" 7 #include <winget/UserSettings.h> 8 #include <winget/LocIndependent.h> 9 10 namespace AppInstaller::CLI 11 { 12 using namespace AppInstaller::CLI::Execution; 13 using namespace Settings; 14 using namespace AppInstaller::Utility::literals; 15 16 namespace 17 { 18 bool ContainsArgumentFromList(const Execution::Args& args, const std::vector<Execution::Args::Type>& argTypes) 19 { 20 return std::any_of(argTypes.begin(), argTypes.end(), [&](Execution::Args::Type arg) { return args.Contains(arg); }); 21 } 22 } 23 24 ArgumentCommon ArgumentCommon::ForType(Execution::Args::Type type) 25 { 26 // A test ensures that all types are listed here 27 switch (type) 28 { 29 // Args to specify where to get app 30 case Execution::Args::Type::Query: 31 return { type, "query"_liv, 'q', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 32 case Execution::Args::Type::MultiQuery: 33 return { type, "query"_liv, 'q', ArgTypeCategory::PackageQuery | ArgTypeCategory::MultiplePackages }; 34 case Execution::Args::Type::Manifest: 35 return { type, "manifest"_liv, 'm', ArgTypeCategory::Manifest }; 36 37 // Query filtering criteria and query behavior 38 case Execution::Args::Type::Id: 39 return { type, "id"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 40 case Execution::Args::Type::Name: 41 return { type, "name"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 42 case Execution::Args::Type::Moniker: 43 return { type, "moniker"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 44 case Execution::Args::Type::Tag: 45 return { type, "tag"_liv, ArgTypeCategory::PackageQuery }; 46 case Execution::Args::Type::Command: 47 return { type, "command"_liv, "cmd"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 48 case Execution::Args::Type::Source: 49 return { type, "source"_liv, 's', ArgTypeCategory::QuerySource }; 50 case Execution::Args::Type::Count: 51 return { type, "count"_liv, 'n', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 52 case Execution::Args::Type::Exact: 53 return { type, "exact"_liv, 'e', ArgTypeCategory::PackageQuery }; 54 55 // Manifest selection behavior after an app is found 56 case Execution::Args::Type::Version: 57 return { type, "version"_liv, 'v', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery }; 58 case Execution::Args::Type::Channel: 59 return { type, "channel"_liv, 'c', ArgTypeCategory::PackageQuery }; 60 61 // Install behavior 62 case Execution::Args::Type::Interactive: 63 return { type, "interactive"_liv, 'i', ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 64 case Execution::Args::Type::Silent: 65 return { type, "silent"_liv, 'h', ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 66 case Execution::Args::Type::Locale: 67 return { type, "locale"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext }; 68 case Execution::Args::Type::Log: 69 return { type, "log"_liv, 'o', ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior }; 70 case Execution::Args::Type::CustomSwitches: 71 return { type, "custom"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior }; 72 case Execution::Args::Type::Override: 73 return { type, "override"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior }; 74 case Execution::Args::Type::InstallLocation: 75 return { type, "location"_liv, 'l', ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior }; 76 case Execution::Args::Type::InstallScope: 77 return { type, "scope"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext }; 78 case Execution::Args::Type::InstallArchitecture: 79 return { type, "architecture"_liv, 'a', ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext }; 80 case Execution::Args::Type::InstallerArchitecture: // Used for input architecture that does not need applicability check. E.g. Download, Show. 81 return { type, "architecture"_liv, 'a', ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext }; 82 case Execution::Args::Type::InstallerType: 83 return { type, "installer-type"_liv, ArgTypeCategory::InstallerSelection }; 84 case Execution::Args::Type::HashOverride: 85 return { type, "ignore-security-hash"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 86 case Execution::Args::Type::IgnoreLocalArchiveMalwareScan: 87 return { type, "ignore-local-archive-malware-scan"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 88 case Execution::Args::Type::AcceptPackageAgreements: 89 return { type, "accept-package-agreements"_liv, ArgTypeCategory::InstallerBehavior }; 90 case Execution::Args::Type::Rename: 91 return { type, "rename"_liv, 'r' }; 92 case Execution::Args::Type::NoUpgrade: 93 return { type, "no-upgrade"_liv, ArgTypeCategory::CopyFlagToSubContext }; 94 case Execution::Args::Type::SkipDependencies: 95 return { type, "skip-dependencies"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 96 case Execution::Args::Type::AllowReboot: 97 return { type, "allow-reboot"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 98 99 // Uninstall behavior 100 case Execution::Args::Type::Purge: 101 return { type, "purge"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PurgePreserve }; 102 case Execution::Args::Type::Preserve: 103 return { type, "preserve"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PurgePreserve }; 104 case Execution::Args::Type::ProductCode: 105 return { type, "product-code"_liv, ArgTypeCategory::SinglePackageQuery }; 106 case Execution::Args::Type::AllVersions: 107 return { type, "all-versions"_liv, "all"_liv, ArgTypeCategory::CopyFlagToSubContext, ArgTypeExclusiveSet::AllAndTargetVersion }; 108 case Execution::Args::Type::TargetVersion: 109 return { type, "version"_liv, 'v', ArgTypeCategory::SinglePackageQuery, ArgTypeExclusiveSet::AllAndTargetVersion }; 110 111 //Source Command 112 case Execution::Args::Type::SourceName: 113 return { type, "name"_liv, 'n' }; 114 case Execution::Args::Type::SourceType: 115 return { type, "type"_liv, 't' }; 116 case Execution::Args::Type::SourceArg: 117 return { type, "arg"_liv, 'a' }; 118 case Execution::Args::Type::ForceSourceReset: 119 return { type, "force"_liv }; 120 case Execution::Args::Type::SourceExplicit: 121 return { type, "explicit"_liv }; 122 case Execution::Args::Type::SourceTrustLevel: 123 return { type, "trust-level"_liv }; 124 125 //Hash Command 126 case Execution::Args::Type::HashFile: 127 return { type, "file"_liv, 'f' }; 128 case Execution::Args::Type::Msix: 129 return { type, "msix"_liv, 'm' }; 130 131 //Validate Command 132 case Execution::Args::Type::ValidateManifest: 133 return { type, "manifest"_liv }; 134 case Execution::Args::Type::IgnoreWarnings: 135 return { type, "ignore-warnings"_liv, "nowarn"_liv}; 136 137 // Complete Command 138 case Execution::Args::Type::Word: 139 return { type, "word"_liv }; 140 case Execution::Args::Type::CommandLine: 141 return { type, "commandline"_liv }; 142 case Execution::Args::Type::Position: 143 return { type, "position"_liv }; 144 145 // Export Command 146 case Execution::Args::Type::IncludeVersions: 147 return { type, "include-versions"_liv }; 148 149 // Import Command 150 case Execution::Args::Type::ImportFile: 151 return { type, "import-file"_liv, 'i' }; 152 case Execution::Args::Type::IgnoreUnavailable: 153 return { type, "ignore-unavailable"_liv }; 154 case Execution::Args::Type::IgnoreVersions: 155 return { type, "ignore-versions"_liv }; 156 157 // Setting Command 158 case Execution::Args::Type::AdminSettingEnable: 159 return { type, "enable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::EnableDisable }; 160 case Execution::Args::Type::AdminSettingDisable: 161 return { type, "disable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::EnableDisable }; 162 case Execution::Args::Type::SettingName: 163 return { type, "setting"_liv }; 164 case Execution::Args::Type::SettingValue: 165 return { type, "value"_liv }; 166 167 // Upgrade command 168 case Execution::Args::Type::All: 169 return { type, "all"_liv, 'r', "recurse"_liv, ArgTypeCategory::MultiplePackages }; 170 case Execution::Args::Type::IncludeUnknown: 171 return { type, "include-unknown"_liv, 'u', "unknown"_liv, ArgTypeCategory::CopyFlagToSubContext }; 172 case Execution::Args::Type::IncludePinned: 173 return { type, "include-pinned"_liv, "pinned"_liv, ArgTypeCategory::CopyFlagToSubContext }; 174 case Execution::Args::Type::UninstallPrevious: 175 return { type, "uninstall-previous"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext }; 176 177 // Show command 178 case Execution::Args::Type::ListVersions: 179 return { type, "versions"_liv }; 180 181 // List command 182 case Execution::Args::Type::Upgrade: 183 return { type, "upgrade-available"_liv}; 184 185 // Pin command 186 case Execution::Args::Type::GatedVersion: 187 return { type, "version"_liv, 'v', ArgTypeCategory::None, ArgTypeExclusiveSet::PinType }; 188 case Execution::Args::Type::BlockingPin: 189 return { type, "blocking"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PinType }; 190 case Execution::Args::Type::PinInstalled: 191 return { type, "installed"_liv, ArgTypeCategory::None }; 192 193 // Error command 194 case Execution::Args::Type::ErrorInput: 195 return { type, "input"_liv, ArgTypeCategory::None }; 196 197 // Resume command 198 case Execution::Args::Type::ResumeId: 199 return { type, "resume-id"_liv, 'g', ArgTypeCategory::None }; 200 case Execution::Args::Type::IgnoreResumeLimit: 201 return { type, "ignore-resume-limit"_liv, ArgTypeCategory::None }; 202 203 // Font command 204 case Execution::Args::Type::Family: 205 return { type, "family"_liv, ArgTypeCategory::None }; 206 207 // Configuration commands 208 case Execution::Args::Type::ConfigurationFile: 209 return { type, "file"_liv, 'f', ArgTypeCategory::ConfigurationSetChoice, ArgTypeExclusiveSet::ConfigurationSetChoice }; 210 case Execution::Args::Type::ConfigurationAcceptWarning: 211 return { type, "accept-configuration-agreements"_liv }; 212 case Execution::Args::Type::ConfigurationSuppressPrologue: 213 return { type, "suppress-initial-details"_liv }; 214 case Execution::Args::Type::ExtendedFeaturesEnable: 215 return { type, "enable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType }; 216 case Execution::Args::Type::ExtendedFeaturesDisable: 217 return { type, "disable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType }; 218 case Execution::Args::Type::ConfigurationModulePath: 219 return { type, "module-path"_liv }; 220 case Execution::Args::Type::ConfigurationProcessorPath: 221 return { type, "processor-path"_liv }; 222 case Execution::Args::Type::ConfigurationExportPackageId: 223 return { type, "package-id"_liv }; 224 case Execution::Args::Type::ConfigurationExportModule: 225 return { type, "module"_liv }; 226 case Execution::Args::Type::ConfigurationExportResource: 227 return { type, "resource"_liv }; 228 case Execution::Args::Type::ConfigurationExportAll: 229 return { type, "all"_liv, 'r', "recurse"_liv }; 230 case Execution::Args::Type::ConfigurationHistoryItem: 231 return { type, "history"_liv, 'h', ArgTypeCategory::ConfigurationSetChoice, ArgTypeExclusiveSet::ConfigurationSetChoice }; 232 case Execution::Args::Type::ConfigurationHistoryRemove: 233 return { type, "remove"_liv }; 234 case Execution::Args::Type::ConfigurationStatusWatch: 235 return { type, "live"_liv }; 236 237 // DSCv3 resources 238 case Execution::Args::Type::DscResourceFunctionGet: 239 return { type, "get"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 240 case Execution::Args::Type::DscResourceFunctionSet: 241 return { type, "set"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 242 case Execution::Args::Type::DscResourceFunctionWhatIf: 243 return { type, "whatIf"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 244 case Execution::Args::Type::DscResourceFunctionTest: 245 return { type, "test"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 246 case Execution::Args::Type::DscResourceFunctionDelete: 247 return { type, "delete"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 248 case Execution::Args::Type::DscResourceFunctionExport: 249 return { type, "export"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 250 case Execution::Args::Type::DscResourceFunctionValidate: 251 return { type, "validate"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 252 case Execution::Args::Type::DscResourceFunctionResolve: 253 return { type, "resolve"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 254 case Execution::Args::Type::DscResourceFunctionAdapter: 255 return { type, "adapter"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 256 case Execution::Args::Type::DscResourceFunctionSchema: 257 return { type, "schema"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 258 case Execution::Args::Type::DscResourceFunctionManifest: 259 return { type, "manifest"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction }; 260 261 // Download command 262 case Execution::Args::Type::DownloadDirectory: 263 return { type, "download-directory"_liv, 'd', ArgTypeCategory::None }; 264 case Execution::Args::Type::Platform: 265 return { type, "platform"_liv, ArgTypeCategory::None }; 266 case Execution::Args::Type::SkipMicrosoftStorePackageLicense: 267 return { type, "skip-microsoft-store-package-license"_liv, "skip-license"_liv, ArgTypeCategory::None }; 268 case Execution::Args::Type::OSVersion: 269 return { type, "os-version"_liv, ArgTypeCategory::None }; 270 271 // Common arguments 272 case Execution::Args::Type::NoVT: 273 return { type, "no-vt"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption }; 274 case Execution::Args::Type::RetroStyle: 275 return { type, "retro"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption }; 276 case Execution::Args::Type::RainbowStyle: 277 return { type, "rainbow"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption }; 278 case Execution::Args::Type::Help: 279 return { type, "help"_liv, APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_CHAR }; 280 case Execution::Args::Type::Info: 281 return { type, "info"_liv }; 282 case Execution::Args::Type::VerboseLogs: 283 return { type, "verbose-logs"_liv, "verbose"_liv }; 284 case Execution::Args::Type::DisableInteractivity: 285 return { type, "disable-interactivity"_liv }; 286 case Execution::Args::Type::Wait: 287 return { type, "wait"_liv }; 288 case Execution::Args::Type::OpenLogs: 289 return { type, "open-logs"_liv, "logs"_liv }; 290 case Execution::Args::Type::Force: 291 return { type, "force"_liv, ArgTypeCategory::CopyFlagToSubContext }; 292 case Execution::Args::Type::OutputFile: 293 return { type, "output"_liv, 'o' }; 294 case Execution::Args::Type::Correlation: 295 return { type, "correlation"_liv }; 296 297 case Execution::Args::Type::DependencySource: 298 return { type, "dependency-source"_liv, ArgTypeCategory::ExtendedSource }; 299 case Execution::Args::Type::CustomHeader: 300 return { type, "header"_liv, ArgTypeCategory::ExtendedSource }; 301 case Execution::Args::Type::AcceptSourceAgreements: 302 return { type, "accept-source-agreements"_liv, ArgTypeCategory::ExtendedSource }; 303 304 case Execution::Args::Type::Proxy: 305 return { type, "proxy"_liv, ArgTypeCategory::CopyValueToSubContext, ArgTypeExclusiveSet::Proxy }; 306 case Execution::Args::Type::NoProxy: 307 return { type, "no-proxy"_liv, ArgTypeCategory::CopyFlagToSubContext, ArgTypeExclusiveSet::Proxy }; 308 309 case Execution::Args::Type::ToolVersion: 310 return { type, "version"_liv, 'v' }; 311 312 // Authentication arguments 313 case Execution::Args::Type::AuthenticationMode: 314 return { type, "authentication-mode"_liv, ArgTypeCategory::CopyValueToSubContext }; 315 case Execution::Args::Type::AuthenticationAccount: 316 return { type, "authentication-account"_liv, ArgTypeCategory::CopyValueToSubContext }; 317 318 // Used for demonstration purposes 319 case Execution::Args::Type::ExperimentalArg: 320 return { type, "arg"_liv }; 321 322 default: 323 THROW_HR(E_UNEXPECTED); 324 } 325 } 326 327 std::vector<ArgumentCommon> ArgumentCommon::GetFromExecArgs(const Execution::Args& execArgs) 328 { 329 auto argTypes = execArgs.GetTypes(); 330 std::vector<ArgumentCommon> result; 331 std::transform(argTypes.begin(), argTypes.end(), std::back_inserter(result), ArgumentCommon::ForType); 332 return result; 333 } 334 335 Argument Argument::ForType(Execution::Args::Type type) 336 { 337 switch (type) 338 { 339 case Args::Type::Query: 340 return Argument{ type, Resource::String::QueryArgumentDescription, ArgumentType::Positional}; 341 case Args::Type::MultiQuery: 342 return Argument{ type, Resource::String::MultiQueryArgumentDescription, ArgumentType::Positional }.SetCountLimit(128); 343 case Args::Type::Manifest: 344 return Argument{ type, Resource::String::ManifestArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, Settings::TogglePolicy::Policy::LocalManifestFiles, Settings::BoolAdminSetting::LocalManifestFiles }; 345 case Args::Type::Id: 346 return Argument{ type, Resource::String::IdArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 347 case Args::Type::Name: 348 return Argument{ type, Resource::String::NameArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 349 case Args::Type::Moniker: 350 return Argument{ type, Resource::String::MonikerArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 351 case Args::Type::Tag: 352 return Argument{ type, Resource::String::TagArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 353 case Args::Type::Command: 354 return Argument{ type, Resource::String::CommandArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 355 case Args::Type::Source: 356 return Argument{ type, Resource::String::SourceArgumentDescription, ArgumentType::Standard }; 357 case Args::Type::DependencySource: 358 return Argument{ type, Resource::String::DependencySourceArgumentDescription, ArgumentType::Standard }; 359 case Args::Type::Count: 360 return Argument{ type, Resource::String::CountArgumentDescription, ArgumentType::Standard }; 361 case Args::Type::Exact: 362 return Argument{ type, Resource::String::ExactArgumentDescription, ArgumentType::Flag }; 363 case Args::Type::Version: 364 return Argument{ type, Resource::String::VersionArgumentDescription, ArgumentType::Standard }; 365 case Args::Type::Channel: 366 return Argument{ type, Resource::String::ChannelArgumentDescription, ArgumentType::Standard, Argument::Visibility::Hidden }; 367 case Args::Type::Interactive: 368 return Argument{ type, Resource::String::InteractiveArgumentDescription, ArgumentType::Flag }; 369 case Args::Type::Silent: 370 return Argument{ type, Resource::String::SilentArgumentDescription, ArgumentType::Flag }; 371 case Args::Type::Locale: 372 return Argument{ type, Resource::String::LocaleArgumentDescription, ArgumentType::Standard }; 373 case Args::Type::InstallArchitecture: 374 return Argument{ type, Resource::String::ArchitectureArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 375 case Args::Type::InstallerArchitecture: 376 return Argument{ type, Resource::String::ArchitectureArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 377 case Args::Type::Log: 378 return Argument{ type, Resource::String::LogArgumentDescription, ArgumentType::Standard }; 379 case Args::Type::CustomSwitches: 380 return Argument{ type, Resource::String::CustomSwitchesArgumentDescription, ArgumentType::Standard }; 381 case Args::Type::Override: 382 return Argument{ type, Resource::String::OverrideArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 383 case Args::Type::InstallLocation: 384 return Argument{ type, Resource::String::LocationArgumentDescription, ArgumentType::Standard }; 385 case Args::Type::HashOverride: 386 return Argument{ type, Resource::String::HashOverrideArgumentDescription, ArgumentType::Flag, Settings::TogglePolicy::Policy::HashOverride, Settings::BoolAdminSetting::InstallerHashOverride }; 387 case Args::Type::AcceptPackageAgreements: 388 return Argument{ type, Resource::String::AcceptPackageAgreementsArgumentDescription, ArgumentType::Flag }; 389 case Args::Type::NoUpgrade: 390 return Argument{ type, Resource::String::NoUpgradeArgumentDescription, ArgumentType::Flag }; 391 case Args::Type::HashFile: 392 return Argument{ type, Resource::String::FileArgumentDescription, ArgumentType::Positional, true }; 393 case Args::Type::Msix: 394 return Argument{ type, Resource::String::MsixArgumentDescription, ArgumentType::Flag }; 395 case Args::Type::ListVersions: 396 return Argument{ type, Resource::String::VersionsArgumentDescription, ArgumentType::Flag }; 397 case Args::Type::Help: 398 return Argument{ type, Resource::String::HelpArgumentDescription, ArgumentType::Flag }; 399 case Args::Type::SkipDependencies: 400 return Argument{ type, Resource::String::SkipDependenciesArgumentDescription, ArgumentType::Flag, false }; 401 case Args::Type::IgnoreLocalArchiveMalwareScan: 402 return Argument{ type, Resource::String::IgnoreLocalArchiveMalwareScanArgumentDescription, ArgumentType::Flag, Settings::TogglePolicy::Policy::LocalArchiveMalwareScanOverride, Settings::BoolAdminSetting::LocalArchiveMalwareScanOverride }; 403 case Args::Type::SourceName: 404 return Argument{ type, Resource::String::SourceNameArgumentDescription, ArgumentType::Positional, false }; 405 case Args::Type::SourceArg: 406 return Argument{ type, Resource::String::SourceArgArgumentDescription, ArgumentType::Positional, true }; 407 case Args::Type::SourceType: 408 return Argument{ type, Resource::String::SourceTypeArgumentDescription, ArgumentType::Positional }; 409 case Args::Type::SourceExplicit: 410 return Argument{ type, Resource::String::SourceExplicitArgumentDescription, ArgumentType::Flag }; 411 case Args::Type::SourceTrustLevel: 412 return Argument{ type, Resource::String::SourceTrustLevelArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 413 case Args::Type::ValidateManifest: 414 return Argument{ type, Resource::String::ValidateManifestArgumentDescription, ArgumentType::Positional, true }; 415 case Args::Type::IgnoreWarnings: 416 return Argument{ type, Resource::String::IgnoreWarningsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help }; 417 case Args::Type::NoVT: 418 return Argument{ type, Resource::String::NoVTArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden }; 419 case Args::Type::RainbowStyle: 420 return Argument{ type, Resource::String::RainbowArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden }; 421 case Args::Type::RetroStyle: 422 return Argument{ type, Resource::String::RetroArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden }; 423 case Args::Type::VerboseLogs: 424 return Argument{ type, Resource::String::VerboseLogsArgumentDescription, ArgumentType::Flag }; 425 case Args::Type::CustomHeader: 426 return Argument{ type, Resource::String::HeaderArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 427 case Args::Type::AcceptSourceAgreements: 428 return Argument{ type, Resource::String::AcceptSourceAgreementsArgumentDescription, ArgumentType::Flag }; 429 case Args::Type::AuthenticationMode: 430 return Argument{ type, Resource::String::AuthenticationModeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 431 case Args::Type::AuthenticationAccount: 432 return Argument{ type, Resource::String::AuthenticationAccountArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help }; 433 case Args::Type::ExperimentalArg: 434 return Argument{ type, Resource::String::ExperimentalArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::ExperimentalArg }; 435 case Args::Type::Rename: 436 return Argument{ type, Resource::String::RenameArgumentDescription, ArgumentType::Standard, false }; 437 case Args::Type::Purge: 438 return Argument{ type, Resource::String::PurgeArgumentDescription, ArgumentType::Flag, false }; 439 case Args::Type::Preserve: 440 return Argument{ type, Resource::String::PreserveArgumentDescription, ArgumentType::Flag, false }; 441 case Args::Type::Wait: 442 return Argument{ type, Resource::String::WaitArgumentDescription, ArgumentType::Flag, false }; 443 case Args::Type::ProductCode: 444 return Argument{ type, Resource::String::ProductCodeArgumentDescription, ArgumentType::Standard, false }; 445 case Args::Type::OpenLogs: 446 return Argument{ type, Resource::String::OpenLogsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help }; 447 case Args::Type::UninstallPrevious: 448 return Argument{ type, Resource::String::UninstallPreviousArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help }; 449 case Args::Type::Force: 450 return Argument{ type, Resource::String::ForceArgumentDescription, ArgumentType::Flag, false }; 451 case Args::Type::DownloadDirectory: 452 return Argument{ type, Resource::String::DownloadDirectoryArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false }; 453 case Args::Type::SkipMicrosoftStorePackageLicense: 454 return Argument{ type, Resource::String::SkipMicrosoftStorePackageLicenseArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help, false }; 455 case Args::Type::Platform: 456 return Argument{ type, Resource::String::PlatformArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false }; 457 case Args::Type::InstallerType: 458 return Argument{ type, Resource::String::InstallerTypeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false }; 459 case Args::Type::ResumeId: 460 return Argument{ type, Resource::String::ResumeIdArgumentDescription, ArgumentType::Standard, true }; 461 case Args::Type::AllowReboot: 462 return Argument{ type, Resource::String::AllowRebootArgumentDescription, ArgumentType::Flag }; 463 case Args::Type::IgnoreResumeLimit: 464 return Argument{ type, Resource::String::IgnoreResumeLimitArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::Resume }; 465 case Args::Type::AllVersions: 466 return Argument{ type, Resource::String::UninstallAllVersionsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help }; 467 case Args::Type::TargetVersion: 468 return Argument{ type, Resource::String::TargetVersionArgumentDescription, ArgumentType::Standard }; 469 case Args::Type::Proxy: 470 return Argument{ type, Resource::String::ProxyArgumentDescription, ArgumentType::Standard, TogglePolicy::Policy::ProxyCommandLineOptions, BoolAdminSetting::ProxyCommandLineOptions }; 471 case Args::Type::NoProxy: 472 return Argument{ type, Resource::String::NoProxyArgumentDescription, ArgumentType::Flag, TogglePolicy::Policy::ProxyCommandLineOptions, BoolAdminSetting::ProxyCommandLineOptions }; 473 case Args::Type::Family: 474 return Argument{ type, Resource::String::FontFamilyNameArgumentDescription, ArgumentType::Positional, false }; 475 case Args::Type::Correlation: 476 return Argument{ type, Resource::String::CorrelationArgumentDescription, ArgumentType::Standard, Argument::Visibility::Hidden }; 477 default: 478 THROW_HR(E_UNEXPECTED); 479 } 480 } 481 482 void Argument::GetCommon(std::vector<Argument>& args) 483 { 484 args.push_back(ForType(Args::Type::Help)); 485 args.push_back(ForType(Args::Type::Wait)); 486 args.push_back(ForType(Args::Type::OpenLogs)); 487 args.push_back(ForType(Args::Type::NoVT)); 488 args.push_back(ForType(Args::Type::RainbowStyle)); 489 args.push_back(ForType(Args::Type::RetroStyle)); 490 args.push_back(ForType(Args::Type::VerboseLogs)); 491 args.push_back(ForType(Args::Type::IgnoreWarnings)); 492 args.emplace_back(Args::Type::DisableInteractivity, Resource::String::DisableInteractivityArgumentDescription, ArgumentType::Flag, false); 493 args.push_back(ForType(Args::Type::Proxy)); 494 args.push_back(ForType(Args::Type::NoProxy)); 495 args.push_back(ForType(Args::Type::Correlation)); 496 } 497 498 std::string Argument::GetUsageString() const 499 { 500 std::ostringstream strstr; 501 if (Alias() != ArgumentCommon::NoAlias) 502 { 503 strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << Alias() << ','; 504 } 505 if (AlternateName() != Argument::NoAlternateName) 506 { 507 strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << AlternateName() << ','; 508 } 509 strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << Name(); 510 return strstr.str(); 511 } 512 513 void Argument::ValidateExclusiveArguments(const Execution::Args& args) 514 { 515 auto argProperties = ArgumentCommon::GetFromExecArgs(args); 516 517 using ExclusiveSet_t = std::underlying_type_t<ArgTypeExclusiveSet>; 518 for (ExclusiveSet_t i = 1 + static_cast<ExclusiveSet_t>(ArgTypeExclusiveSet::None); i < static_cast<ExclusiveSet_t>(ArgTypeExclusiveSet::Max); i <<= 1) 519 { 520 std::vector<ArgumentCommon> argsFromSet; 521 std::copy_if( 522 argProperties.begin(), 523 argProperties.end(), 524 std::back_inserter(argsFromSet), 525 [=](const ArgumentCommon& arg) { return static_cast<ExclusiveSet_t>(arg.ExclusiveSet) & i; }); 526 527 if (argsFromSet.size() > 1) 528 { 529 // Create a string showing the exclusive args. 530 std::string argsString; 531 for (const auto& arg : argsFromSet) 532 { 533 if (!argsString.empty()) 534 { 535 argsString += '|'; 536 537 } 538 539 argsString += arg.Name; 540 } 541 542 throw CommandException(Resource::String::MultipleExclusiveArgumentsProvided(Utility::LocIndString{ argsString })); 543 } 544 } 545 } 546 547 void Argument::ValidateArgumentDependency(const Execution::Args& args, Execution::Args::Type type, Execution::Args::Type dependencyArgType) 548 { 549 if (args.Contains(type) && !args.Contains(dependencyArgType)) 550 { 551 throw CommandException(Resource::String::DependencyArgumentMissing( 552 Utility::LocIndString{ ArgumentCommon::ForType(type).Name }, 553 Utility::LocIndString{ ArgumentCommon::ForType(dependencyArgType).Name })); 554 } 555 } 556 557 ArgTypeCategory Argument::GetCategoriesPresent(const Execution::Args& args) 558 { 559 auto argProperties = ArgumentCommon::GetFromExecArgs(args); 560 561 ArgTypeCategory result = ArgTypeCategory::None; 562 for (const auto& arg : argProperties) 563 { 564 result |= arg.TypeCategory; 565 } 566 567 return result; 568 } 569 570 ArgTypeCategory Argument::GetCategoriesAndValidateCommonArguments(const Execution::Args& args, bool requirePackageSelectionArg) 571 { 572 const auto categories = GetCategoriesPresent(args); 573 574 // Commands like install require some argument to select a package 575 if (requirePackageSelectionArg) 576 { 577 if (WI_AreAllFlagsClear(categories, ArgTypeCategory::Manifest | ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery)) 578 { 579 throw CommandException(Resource::String::NoPackageSelectionArgumentProvided); 580 } 581 } 582 583 // If a manifest is specified, we cannot also have arguments for searching 584 if (WI_IsFlagSet(categories, ArgTypeCategory::Manifest) && 585 WI_IsAnyFlagSet(categories, ArgTypeCategory::PackageQuery | ArgTypeCategory::QuerySource)) 586 { 587 throw CommandException(Resource::String::BothManifestAndSearchQueryProvided); 588 } 589 590 // If we have multiple packages, we cannot have arguments that only make sense for a single package 591 if (WI_IsFlagSet(categories, ArgTypeCategory::MultiplePackages) && 592 WI_IsAnyFlagSet(categories, ArgTypeCategory::SinglePackageQuery | ArgTypeCategory::SingleInstallerBehavior)) 593 { 594 throw CommandException(Resource::String::ArgumentForSinglePackageProvidedWithMultipleQueries); 595 } 596 597 return categories; 598 } 599 600 Argument::Visibility Argument::GetVisibility() const 601 { 602 if (!ExperimentalFeature::IsEnabled(m_feature)) 603 { 604 return Argument::Visibility::Hidden; 605 } 606 607 if (!GroupPolicies().IsEnabled(m_groupPolicy)) 608 { 609 return Argument::Visibility::Hidden; 610 } 611 612 return m_visibility; 613 } 614 }