From ec2e9632b0b6b58cb20759490e48d687ead22668 Mon Sep 17 00:00:00 2001 From: David Bennett Date: Mon, 15 Sep 2025 09:09:18 -0700 Subject: [PATCH 1/6] Schema update --- .../latest/manifest.installer.latest.json | 1471 ++++++++------- .../latest/manifest.singleton.latest.json | 1645 +++++++++-------- .../TestData/ManifestV1_12-Singleton.yaml | 8 + .../ManifestV1_12-MultiFile-Installer.yaml | 14 + .../Manifest/YamlWriter.cpp | 6 +- 5 files changed, 1660 insertions(+), 1484 deletions(-) diff --git a/schemas/JSON/manifests/latest/manifest.installer.latest.json b/schemas/JSON/manifests/latest/manifest.installer.latest.json index 2f634646d9..c902789a5c 100644 --- a/schemas/JSON/manifests/latest/manifest.installer.latest.json +++ b/schemas/JSON/manifests/latest/manifest.installer.latest.json @@ -2,778 +2,851 @@ "$id": "https://aka.ms/winget-manifest.installer.1.12.0.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "A representation of a single-file manifest representing an app installers in the OWC. v1.12.0", - "definitions": { - "PackageIdentifier": { - "type": "string", - "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", - "maxLength": 128, - "description": "The package unique identifier" - }, - "PackageVersion": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 128, - "description": "The package version" - }, - "Locale": { - "type": [ "string", "null" ], - "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", - "maxLength": 20, - "description": "The installer meta-data locale" - }, - "Channel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 16, - "description": "The distribution channel" - }, - "Platform": { - "type": [ "array", "null" ], - "items": { - "title": "Platform", - "type": "string", - "enum": [ - "Windows.Desktop", - "Windows.Universal" - ] - }, - "maxItems": 2, - "uniqueItems": true, - "description": "The installer supported operating system" - }, - "MinimumOSVersion": { - "type": [ "string", "null" ], - "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", - "description": "The installer minimum operating system version" - }, - "Url": { - "type": [ "string", "null" ], - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "Url type" - }, - "InstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "zip", - "inno", - "nullsoft", - "wix", - "burn", - "pwa", - "portable", - "font" - ], - "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" - }, - "NestedInstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "inno", - "nullsoft", - "wix", - "burn", - "portable", - "font" - ], - "description": "Enumeration of supported nested installer types contained inside an archive file" - }, - "NestedInstallerFiles": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "NestedInstallerFile", - "properties": { - "RelativeFilePath": { + "definitions": { + "PackageIdentifier": { "type": "string", - "minLength": 1, - "maxLength": 512, - "description": "The relative path to the nested installer file" - }, - "PortableCommandAlias": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 40, - "description": "The command alias to be used for calling the package. Only applies to the nested portable package" - } + "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", + "maxLength": 128, + "description": "The package unique identifier" }, - "required": [ "RelativeFilePath" ], - "description": "A nested installer file contained inside an archive" - }, - "maxItems": 1024, - "description": "List of nested installer files contained inside an archive" - }, - "Architecture": { - "type": "string", - "enum": [ - "x86", - "x64", - "arm", - "arm64", - "neutral" - ], - "description": "The installer target architecture" - }, - "Scope": { - "type": [ "string", "null" ], - "enum": [ - "user", - "machine" - ], - "description": "Scope indicates if the installer is per user or per machine" - }, - "InstallModes": { - "type": [ "array", "null" ], - "items": { - "title": "InstallModes", - "type": "string", - "enum": [ - "interactive", - "silent", - "silentWithProgress" - ] - }, - "maxItems": 3, - "uniqueItems": true, - "description": "List of supported installer modes" - }, - "InstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" - }, - "InstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Upgrade": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the installer by winget" - }, - "Repair": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair." - } - } - }, - "InstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the installer after execution" - }, - "InstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero installer success exit codes other than known default values by winget" - }, - "ExpectedReturnCodes": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "ExpectedReturnCode", - "properties": { - "InstallerReturnCode": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "ReturnResponse": { + "PackageVersion": { "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, - "ReturnResponseUrl": { - "$ref": "#/definitions/Url", - "description": "The return response url to provide additional guidance for expected return codes" - } + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 128, + "description": "The package version" }, - "required": [ "InstallerReturnCode", "ReturnResponse" ] - }, - "maxItems": 128, - "description": "Installer exit codes for common errors" - }, - "UpgradeBehavior": { - "type": [ "string", "null" ], - "enum": [ - "install", - "uninstallPrevious", - "deny" - ], - "description": "The upgrade method" - }, - "Commands": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of commands or aliases to run the package" - }, - "Protocols": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "maxLength": 2048 - }, - "maxItems": 64, - "uniqueItems": true, - "description": "List of protocols the package provides a handler for" - }, - "FileExtensions": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 64 - }, - "maxItems": 512, - "uniqueItems": true, - "description": "List of file extensions the package could support" - }, - "Dependencies": { - "type": [ "object", "null" ], - "properties": { - "WindowsFeatures": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows feature dependencies" - }, - "WindowsLibraries": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows library dependencies" - }, - "PackageDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "properties": { - "PackageIdentifier": { - "$ref": "#/definitions/PackageIdentifier" - }, - "MinimumVersion": { - "$ref": "#/definitions/PackageVersion" - } - }, - "required": [ "PackageIdentifier" ] - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of package dependencies from current source" - }, - "ExternalDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of external package dependencies" - } - } - }, - "PackageFamilyName": { - "type": [ "string", "null" ], - "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", - "maxLength": 255, - "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" - }, - "ProductCode": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 255, - "description": "ProductCode could be used for correlation of packages across sources" - }, - "Capabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer capabilities" - }, - "RestrictedCapabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer restricted capabilities" - }, - "Market": { - "type": "string", - "pattern": "^[A-Z]{2}$", - "description": "The installer target market" - }, - "MarketArray": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 256, - "items": { - "$ref": "#/definitions/Market" - }, - "description": "Array of markets" - }, - "Markets": { - "description": "The installer markets", - "type": [ "object", "null" ], - "oneOf": [ - { - "properties": { - "AllowedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "AllowedMarkets" ] - }, - { - "properties": { - "ExcludedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "ExcludedMarkets" ] - } - ] - }, - "InstallerAbortsTerminal": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer will abort terminal. Default is false" - }, - "ReleaseDate": { - "type": [ "string", "null" ], - "format": "date", - "description": "The installer release date" - }, - "InstallLocationRequired": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer requires an install location provided" - }, - "RequireExplicitUpgrade": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer should be pinned by default from upgrade" - }, - "DisplayInstallWarnings": { - "type": [ "boolean", "null" ], - "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." - }, - "UnsupportedOSArchitectures": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedOSArchitecture", - "enum": [ - "x86", - "x64", - "arm", - "arm64" - ] - }, - "description": "List of OS architectures the installer does not support" - }, - "UnsupportedArguments": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedArgument", - "enum": [ - "log", - "location" - ] - }, - "description": "List of winget arguments the installer does not support" - }, - "AppsAndFeaturesEntry": { - "type": "object", - "properties": { - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The DisplayName registry value" - }, - "Publisher": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The Publisher registry value" - }, - "DisplayVersion": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 128, - "description": "The DisplayVersion registry value" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" + "Locale": { + "type": [ "string", "null" ], + "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", + "maxLength": 20, + "description": "The installer meta-data locale" }, - "UpgradeCode": { - "$ref": "#/definitions/ProductCode" + "Channel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 16, + "description": "The distribution channel" }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - } - }, - "description": "Various key values under installer's ARP entry" - }, - "AppsAndFeaturesEntries": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 128, - "items": { - "$ref": "#/definitions/AppsAndFeaturesEntry" - }, - "description": "List of ARP entries." - }, - "ElevationRequirement": { - "type": [ "string", "null" ], - "enum": [ - "elevationRequired", - "elevationProhibited", - "elevatesSelf" - ], - "description": "The installer's elevation requirement" - }, - "InstallationMetadata": { - "type": "object", - "title": "InstallationMetadata", - "properties": { - "DefaultInstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Represents the default installed package location. Used for deeper installation detection." - }, - "Files": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 2048, - "items": { - "type": "object", - "title": "InstalledFile", - "properties": { - "RelativeFilePath": { + "Platform": { + "type": [ "array", "null" ], + "items": { + "title": "Platform", "type": "string", - "minLength": 1, - "maxLength": 2048, - "description": "The relative path to the installed file." - }, - "FileSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the installed file." - }, - "FileType": { - "type": [ "string", "null" ], "enum": [ - "launch", - "uninstall", - "other" - ], - "description": "The optional installed file type. If not specified, the file is treated as other." - }, - "InvocationParameter": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Optional parameter for invocable files." - }, - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "Optional display name for invocable files." - } + "Windows.Desktop", + "Windows.Universal" + ] }, - "required": [ "RelativeFilePath" ], - "description": "Represents an installed file." - }, - "description": "List of installed files." - } - }, - "description": "Details about the installation. Used for deeper installation detection." - }, - "DownloadCommandProhibited": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." - }, - "RepairBehavior": { - "type": [ "string", "null" ], - "enum": [ - "modify", - "uninstaller", - "installer" - ], - "description": "The repair method" - }, - "ArchiveBinariesDependOnPath": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." - }, - "Authentication": { - "type": [ "object", "null" ], - "properties": { - "AuthenticationType": { - "type": "string", - "enum": [ - "none", - "microsoftEntraId", - "microsoftEntraIdForAzureBlobStorage" - ], - "description": "The authentication type" - }, - "MicrosoftEntraIdAuthenticationInfo": { - "type": [ "object", "null" ], - "properties": { - "Resource": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The resource value for Microsoft Entra Id authentication." - }, - "Scope": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The scope value for Microsoft Entra Id authentication." - } - }, - "description": "The Microsoft Entra Id authentication info" - } - }, - "required": [ - "AuthenticationType" - ], - "description": "The authentication requirement for downloading the installer." - }, - "Installer": { - "type": "object", - "properties": { - "InstallerLocale": { - "$ref": "#/definitions/Locale" - }, - "Platform": { - "$ref": "#/definitions/Platform" + "maxItems": 2, + "uniqueItems": true, + "description": "The installer supported operating system" }, "MinimumOSVersion": { - "$ref": "#/definitions/MinimumOSVersion" + "type": [ "string", "null" ], + "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", + "description": "The installer minimum operating system version" }, - "Architecture": { - "$ref": "#/definitions/Architecture" + "Url": { + "type": [ "string", "null" ], + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "Url type" }, "InstallerType": { - "$ref": "#/definitions/InstallerType" + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "zip", + "inno", + "nullsoft", + "wix", + "burn", + "pwa", + "portable", + "font" + ], + "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" }, "NestedInstallerType": { - "$ref": "#/definitions/NestedInstallerType" + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "inno", + "nullsoft", + "wix", + "burn", + "portable", + "font" + ], + "description": "Enumeration of supported nested installer types contained inside an archive file" }, "NestedInstallerFiles": { - "$ref": "#/definitions/NestedInstallerFiles" - }, - "Scope": { - "$ref": "#/definitions/Scope" - }, - "InstallerUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The installer Url" + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "NestedInstallerFile", + "properties": { + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "description": "The relative path to the nested installer file" + }, + "PortableCommandAlias": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 40, + "description": "The command alias to be used for calling the package. Only applies to the nested portable package" + } + }, + "required": [ "RelativeFilePath" ], + "description": "A nested installer file contained inside an archive" + }, + "maxItems": 1024, + "description": "List of nested installer files contained inside an archive" }, - "InstallerSha256": { - "type": "string", - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Sha256 is required. Sha256 of the installer" + "Architecture": { + "type": "string", + "enum": [ + "x86", + "x64", + "arm", + "arm64", + "neutral" + ], + "description": "The installer target architecture" }, - "SignatureSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" + "Scope": { + "type": [ "string", "null" ], + "enum": [ + "user", + "machine" + ], + "description": "Scope indicates if the installer is per user or per machine" }, "InstallModes": { - "$ref": "#/definitions/InstallModes" + "type": [ "array", "null" ], + "items": { + "title": "InstallModes", + "type": "string", + "enum": [ + "interactive", + "silent", + "silentWithProgress" + ] + }, + "maxItems": 3, + "uniqueItems": true, + "description": "List of supported installer modes" }, "InstallerSwitches": { - "$ref": "#/definitions/InstallerSwitches" + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" + }, + "InstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Upgrade": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the installer by winget" + }, + "Repair": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair." + } + } + }, + "InstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the installer after execution" }, "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero installer success exit codes other than known default values by winget" + }, + "UninstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the uninstaller by winget" + } + } + }, + "UninstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the uninstaller after execution" + }, + "UninstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + }, + "ReturnResponse": { + "type": "string", + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] }, "ExpectedReturnCodes": { - "$ref": "#/definitions/ExpectedReturnCodes" + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "ExpectedReturnCode", + "properties": { + "InstallerReturnCode": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "UninstallerReturnCode": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "ReturnResponse": { + "$ref": "#/definitions/ReturnResponse" + }, + "ReturnResponseUrl": { + "$ref": "#/definitions/Url", + "description": "The return response url to provide additional guidance for expected return codes" + } + }, + "anyOf": [ + { + "required:": [ "InstallerReturnCode", "ReturnResponse" ] + }, + { + "required": [ "UninstallerReturnCode", "ReturnResponse" ] + } + ] + }, + "maxItems": 128, + "description": "Installer exit codes for common errors" }, "UpgradeBehavior": { - "$ref": "#/definitions/UpgradeBehavior" + "type": [ "string", "null" ], + "enum": [ + "install", + "uninstallPrevious", + "deny" + ], + "description": "The upgrade method" }, "Commands": { - "$ref": "#/definitions/Commands" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of commands or aliases to run the package" }, "Protocols": { - "$ref": "#/definitions/Protocols" + "type": [ "array", "null" ], + "items": { + "type": "string", + "maxLength": 2048 + }, + "maxItems": 64, + "uniqueItems": true, + "description": "List of protocols the package provides a handler for" }, "FileExtensions": { - "$ref": "#/definitions/FileExtensions" + "type": [ "array", "null" ], + "items": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 64 + }, + "maxItems": 512, + "uniqueItems": true, + "description": "List of file extensions the package could support" }, "Dependencies": { - "$ref": "#/definitions/Dependencies" + "type": [ "object", "null" ], + "properties": { + "WindowsFeatures": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows feature dependencies" + }, + "WindowsLibraries": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows library dependencies" + }, + "PackageDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "properties": { + "PackageIdentifier": { + "$ref": "#/definitions/PackageIdentifier" + }, + "MinimumVersion": { + "$ref": "#/definitions/PackageVersion" + } + }, + "required": [ "PackageIdentifier" ] + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of package dependencies from current source" + }, + "ExternalDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of external package dependencies" + } + } }, "PackageFamilyName": { - "$ref": "#/definitions/PackageFamilyName" + "type": [ "string", "null" ], + "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", + "maxLength": 255, + "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" }, "ProductCode": { - "$ref": "#/definitions/ProductCode" + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 255, + "description": "ProductCode could be used for correlation of packages across sources" }, "Capabilities": { - "$ref": "#/definitions/Capabilities" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer capabilities" }, "RestrictedCapabilities": { - "$ref": "#/definitions/RestrictedCapabilities" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer restricted capabilities" + }, + "Market": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "description": "The installer target market" + }, + "MarketArray": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 256, + "items": { + "$ref": "#/definitions/Market" + }, + "description": "Array of markets" }, "Markets": { - "$ref": "#/definitions/Markets" + "description": "The installer markets", + "type": [ "object", "null" ], + "oneOf": [ + { + "properties": { + "AllowedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "AllowedMarkets" ] + }, + { + "properties": { + "ExcludedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "ExcludedMarkets" ] + } + ] }, "InstallerAbortsTerminal": { - "$ref": "#/definitions/InstallerAbortsTerminal" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer will abort terminal. Default is false" }, "ReleaseDate": { - "$ref": "#/definitions/ReleaseDate" + "type": [ "string", "null" ], + "format": "date", + "description": "The installer release date" }, "InstallLocationRequired": { - "$ref": "#/definitions/InstallLocationRequired" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer requires an install location provided" }, "RequireExplicitUpgrade": { - "$ref": "#/definitions/RequireExplicitUpgrade" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer should be pinned by default from upgrade" }, "DisplayInstallWarnings": { - "$ref": "#/definitions/DisplayInstallWarnings" + "type": [ "boolean", "null" ], + "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." }, "UnsupportedOSArchitectures": { - "$ref": "#/definitions/UnsupportedOSArchitectures" + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedOSArchitecture", + "enum": [ + "x86", + "x64", + "arm", + "arm64" + ] + }, + "description": "List of OS architectures the installer does not support" }, "UnsupportedArguments": { - "$ref": "#/definitions/UnsupportedArguments" + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedArgument", + "enum": [ + "log", + "location" + ] + }, + "description": "List of winget arguments the installer does not support" + }, + "AppsAndFeaturesEntry": { + "type": "object", + "properties": { + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The DisplayName registry value" + }, + "Publisher": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The Publisher registry value" + }, + "DisplayVersion": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 128, + "description": "The DisplayVersion registry value" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "UpgradeCode": { + "$ref": "#/definitions/ProductCode" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + } + }, + "description": "Various key values under installer's ARP entry" }, "AppsAndFeaturesEntries": { - "$ref": "#/definitions/AppsAndFeaturesEntries" + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 128, + "items": { + "$ref": "#/definitions/AppsAndFeaturesEntry" + }, + "description": "List of ARP entries." }, "ElevationRequirement": { - "$ref": "#/definitions/ElevationRequirement" + "type": [ "string", "null" ], + "enum": [ + "elevationRequired", + "elevationProhibited", + "elevatesSelf" + ], + "description": "The installer's elevation requirement" }, "InstallationMetadata": { - "$ref": "#/definitions/InstallationMetadata" + "type": "object", + "title": "InstallationMetadata", + "properties": { + "DefaultInstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Represents the default installed package location. Used for deeper installation detection." + }, + "Files": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 2048, + "items": { + "type": "object", + "title": "InstalledFile", + "properties": { + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 2048, + "description": "The relative path to the installed file." + }, + "FileSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the installed file." + }, + "FileType": { + "type": [ "string", "null" ], + "enum": [ + "launch", + "uninstall", + "other" + ], + "description": "The optional installed file type. If not specified, the file is treated as other." + }, + "InvocationParameter": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Optional parameter for invocable files." + }, + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "Optional display name for invocable files." + } + }, + "required": [ "RelativeFilePath" ], + "description": "Represents an installed file." + }, + "description": "List of installed files." + } + }, + "description": "Details about the installation. Used for deeper installation detection." }, "DownloadCommandProhibited": { - "$ref": "#/definitions/DownloadCommandProhibited" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." }, "RepairBehavior": { - "$ref": "#/definitions/RepairBehavior" + "type": [ "string", "null" ], + "enum": [ + "modify", + "uninstaller", + "installer" + ], + "description": "The repair method" }, "ArchiveBinariesDependOnPath": { - "$ref": "#/definitions/ArchiveBinariesDependOnPath" + "type": [ "boolean", "null" ], + "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." }, "Authentication": { - "$ref": "#/definitions/Authentication" + "type": [ "object", "null" ], + "properties": { + "AuthenticationType": { + "type": "string", + "enum": [ + "none", + "microsoftEntraId", + "microsoftEntraIdForAzureBlobStorage" + ], + "description": "The authentication type" + }, + "MicrosoftEntraIdAuthenticationInfo": { + "type": [ "object", "null" ], + "properties": { + "Resource": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The resource value for Microsoft Entra Id authentication." + }, + "Scope": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The scope value for Microsoft Entra Id authentication." + } + }, + "description": "The Microsoft Entra Id authentication info" + } + }, + "required": [ + "AuthenticationType" + ], + "description": "The authentication requirement for downloading the installer." + }, + "Installer": { + "type": "object", + "properties": { + "InstallerLocale": { + "$ref": "#/definitions/Locale" + }, + "Platform": { + "$ref": "#/definitions/Platform" + }, + "MinimumOSVersion": { + "$ref": "#/definitions/MinimumOSVersion" + }, + "Architecture": { + "$ref": "#/definitions/Architecture" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + }, + "NestedInstallerType": { + "$ref": "#/definitions/NestedInstallerType" + }, + "NestedInstallerFiles": { + "$ref": "#/definitions/NestedInstallerFiles" + }, + "Scope": { + "$ref": "#/definitions/Scope" + }, + "InstallerUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The installer Url" + }, + "InstallerSha256": { + "type": "string", + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Sha256 is required. Sha256 of the installer" + }, + "SignatureSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" + }, + "InstallModes": { + "$ref": "#/definitions/InstallModes" + }, + "InstallerSwitches": { + "$ref": "#/definitions/InstallerSwitches" + }, + "InstallerSuccessCodes": { + "$ref": "#/definitions/InstallerSuccessCodes" + }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" + }, + "ExpectedReturnCodes": { + "$ref": "#/definitions/ExpectedReturnCodes" + }, + "UpgradeBehavior": { + "$ref": "#/definitions/UpgradeBehavior" + }, + "Commands": { + "$ref": "#/definitions/Commands" + }, + "Protocols": { + "$ref": "#/definitions/Protocols" + }, + "FileExtensions": { + "$ref": "#/definitions/FileExtensions" + }, + "Dependencies": { + "$ref": "#/definitions/Dependencies" + }, + "PackageFamilyName": { + "$ref": "#/definitions/PackageFamilyName" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "Capabilities": { + "$ref": "#/definitions/Capabilities" + }, + "RestrictedCapabilities": { + "$ref": "#/definitions/RestrictedCapabilities" + }, + "Markets": { + "$ref": "#/definitions/Markets" + }, + "InstallerAbortsTerminal": { + "$ref": "#/definitions/InstallerAbortsTerminal" + }, + "ReleaseDate": { + "$ref": "#/definitions/ReleaseDate" + }, + "InstallLocationRequired": { + "$ref": "#/definitions/InstallLocationRequired" + }, + "RequireExplicitUpgrade": { + "$ref": "#/definitions/RequireExplicitUpgrade" + }, + "DisplayInstallWarnings": { + "$ref": "#/definitions/DisplayInstallWarnings" + }, + "UnsupportedOSArchitectures": { + "$ref": "#/definitions/UnsupportedOSArchitectures" + }, + "UnsupportedArguments": { + "$ref": "#/definitions/UnsupportedArguments" + }, + "AppsAndFeaturesEntries": { + "$ref": "#/definitions/AppsAndFeaturesEntries" + }, + "ElevationRequirement": { + "$ref": "#/definitions/ElevationRequirement" + }, + "InstallationMetadata": { + "$ref": "#/definitions/InstallationMetadata" + }, + "DownloadCommandProhibited": { + "$ref": "#/definitions/DownloadCommandProhibited" + }, + "RepairBehavior": { + "$ref": "#/definitions/RepairBehavior" + }, + "ArchiveBinariesDependOnPath": { + "$ref": "#/definitions/ArchiveBinariesDependOnPath" + }, + "Authentication": { + "$ref": "#/definitions/Authentication" + } + }, + "required": [ + "Architecture", + "InstallerUrl", + "InstallerSha256" + ] } - }, - "required": [ - "Architecture", - "InstallerUrl", - "InstallerSha256" - ] - } - }, + }, "type": "object", "properties": { "PackageIdentifier": { @@ -813,7 +886,13 @@ "$ref": "#/definitions/InstallerSwitches" }, "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" + "$ref": "#/definitions/InstallerSuccessCodes" + }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" }, "ExpectedReturnCodes": { "$ref": "#/definitions/ExpectedReturnCodes" diff --git a/schemas/JSON/manifests/latest/manifest.singleton.latest.json b/schemas/JSON/manifests/latest/manifest.singleton.latest.json index 9a44532d61..4d4b89ea80 100644 --- a/schemas/JSON/manifests/latest/manifest.singleton.latest.json +++ b/schemas/JSON/manifests/latest/manifest.singleton.latest.json @@ -2,879 +2,952 @@ "$id": "https://aka.ms/winget-manifest.singleton.1.12.0.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "A representation of a single-file manifest representing an app in the OWC. v1.12.0", - "definitions": { - "PackageIdentifier": { - "type": "string", - "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", - "maxLength": 128, - "description": "The package unique identifier" - }, - "PackageVersion": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 128, - "description": "The package version" - }, - "Locale": { - "type": [ "string", "null" ], - "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", - "maxLength": 20, - "description": "The package meta-data locale" - }, - "Url": { - "type": [ "string", "null" ], - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "Optional Url type" - }, - "Tag": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 40, - "description": "Package moniker or tag" - }, - "Agreement": { - "type": "object", - "properties": { - "AgreementLabel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 100, - "description": "The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel" - }, - "Agreement": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 10000, - "description": "The agreement text content." - }, - "AgreementUrl": { - "$ref": "#/definitions/Url", - "description": "The agreement URL." - } - } - }, - "Documentation": { - "type": "object", - "properties": { - "DocumentLabel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 100, - "description": "The label of the documentation for providing software guides such as manuals and troubleshooting URLs." - }, - "DocumentUrl": { - "$ref": "#/definitions/Url", - "description": "The documentation URL." - } - } - }, - "Icon": { - "type": "object", - "properties": { - "IconUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The url of the hosted icon file" + "definitions": { + "PackageIdentifier": { + "type": "string", + "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", + "maxLength": 128, + "description": "The package unique identifier" }, - "IconFileType": { - "type": "string", - "enum": [ - "png", - "jpeg", - "ico" - ], - "description": "The icon file type" + "PackageVersion": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 128, + "description": "The package version" }, - "IconResolution": { - "type": [ "string", "null" ], - "enum": [ - "custom", - "16x16", - "20x20", - "24x24", - "30x30", - "32x32", - "36x36", - "40x40", - "48x48", - "60x60", - "64x64", - "72x72", - "80x80", - "96x96", - "256x256" - ], - "description": "Optional icon resolution" + "Locale": { + "type": [ "string", "null" ], + "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", + "maxLength": 20, + "description": "The package meta-data locale" }, - "IconTheme": { - "type": [ "string", "null" ], - "enum": [ - "default", - "light", - "dark", - "highContrast" - ], - "description": "Optional icon theme" + "Url": { + "type": [ "string", "null" ], + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "Optional Url type" }, - "IconSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the icon file" - } - }, - "required": [ - "IconUrl", - "IconFileType" - ] - }, - "Channel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 16, - "description": "The distribution channel" - }, - "Platform": { - "type": [ "array", "null" ], - "items": { - "title": "Platform", - "type": "string", - "enum": [ - "Windows.Desktop", - "Windows.Universal" - ] - }, - "maxItems": 2, - "uniqueItems": true, - "description": "The installer supported operating system" - }, - "MinimumOSVersion": { - "type": [ "string", "null" ], - "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", - "description": "The installer minimum operating system version" - }, - "InstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "zip", - "inno", - "nullsoft", - "wix", - "burn", - "pwa", - "portable", - "font" - ], - "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" - }, - "NestedInstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "inno", - "nullsoft", - "wix", - "burn", - "portable", - "font" - ], - "description": "Enumeration of supported nested installer types contained inside an archive file" - }, - "NestedInstallerFiles": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "NestedInstallerFile", - "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "description": "The relative path to the nested installer file" - }, - "PortableCommandAlias": { + "Tag": { "type": [ "string", "null" ], "minLength": 1, "maxLength": 40, - "description": "The command alias to be used for calling the package. Only applies to the nested portable package" - } - }, - "required": [ "RelativeFilePath" ], - "description": "A nested installer file contained inside an archive" - }, - "maxItems": 1024, - "description": "List of nested installer files contained inside an archive" - }, - "Architecture": { - "type": "string", - "enum": [ - "x86", - "x64", - "arm", - "arm64", - "neutral" - ], - "description": "The installer target architecture" - }, - "Scope": { - "type": [ "string", "null" ], - "enum": [ - "user", - "machine" - ], - "description": "Scope indicates if the installer is per user or per machine" - }, - "InstallModes": { - "type": [ "array", "null" ], - "items": { - "title": "InstallModes", - "type": "string", - "enum": [ - "interactive", - "silent", - "silentWithProgress" - ] - }, - "maxItems": 3, - "uniqueItems": true, - "description": "List of supported installer modes" - }, - "InstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" - }, - "InstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Upgrade": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the installer by winget" + "description": "Package moniker or tag" }, - "Repair": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair" - } - } - }, - "InstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the installer after execution" - }, - "InstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero installer success exit codes other than known default values by winget" - }, - "ExpectedReturnCodes": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "ExpectedReturnCode", - "properties": { - "InstallerReturnCode": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "ReturnResponse": { - "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, - "ReturnResponseUrl": { - "$ref": "#/definitions/Url", - "description": "The return response url to provide additional guidance for expected return codes" - } - }, - "required": [ "InstallerReturnCode", "ReturnResponse" ] - }, - "maxItems": 128, - "description": "Installer exit codes for common errors" - }, - "UpgradeBehavior": { - "type": [ "string", "null" ], - "enum": [ - "install", - "uninstallPrevious", - "deny" - ], - "description": "The upgrade method" - }, - "Commands": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of commands or aliases to run the package" - }, - "Protocols": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "maxLength": 2048 - }, - "maxItems": 64, - "uniqueItems": true, - "description": "List of protocols the package provides a handler for" - }, - "FileExtensions": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 64 - }, - "maxItems": 512, - "uniqueItems": true, - "description": "List of file extensions the package could support" - }, - "Dependencies": { - "type": [ "object", "null" ], - "properties": { - "WindowsFeatures": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows feature dependencies" - }, - "WindowsLibraries": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows library dependencies" - }, - "PackageDependencies": { - "type": [ "array", "null" ], - "items": { + "Agreement": { "type": "object", "properties": { - "PackageIdentifier": { - "$ref": "#/definitions/PackageIdentifier" - }, - "MinimumVersion": { - "$ref": "#/definitions/PackageVersion" - } - }, - "required": [ "PackageIdentifier" ] - }, - "maxItems": 16, - "description": "List of package dependencies from current source" - }, - "ExternalDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of external package dependencies" - } - } - }, - "PackageFamilyName": { - "type": [ "string", "null" ], - "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", - "maxLength": 255, - "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" - }, - "ProductCode": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 255, - "description": "ProductCode could be used for correlation of packages across sources" - }, - "Capabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer capabilities" - }, - "RestrictedCapabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer restricted capabilities" - }, - "Market": { - "type": "string", - "pattern": "^[A-Z]{2}$", - "description": "The installer target market" - }, - "MarketArray": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 256, - "items": { - "$ref": "#/definitions/Market" - }, - "description": "Array of markets" - }, - "Markets": { - "description": "The installer markets", - "type": [ "object", "null" ], - "oneOf": [ - { - "properties": { - "AllowedMarkets": { - "$ref": "#/definitions/MarketArray" + "AgreementLabel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 100, + "description": "The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel" + }, + "Agreement": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 10000, + "description": "The agreement text content." + }, + "AgreementUrl": { + "$ref": "#/definitions/Url", + "description": "The agreement URL." + } } - }, - "required": [ "AllowedMarkets" ] }, - { - "properties": { - "ExcludedMarkets": { - "$ref": "#/definitions/MarketArray" + "Documentation": { + "type": "object", + "properties": { + "DocumentLabel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 100, + "description": "The label of the documentation for providing software guides such as manuals and troubleshooting URLs." + }, + "DocumentUrl": { + "$ref": "#/definitions/Url", + "description": "The documentation URL." + } } - }, - "required": [ "ExcludedMarkets" ] - } - ] - }, - "InstallerAbortsTerminal": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer will abort terminal. Default is false" - }, - "ReleaseDate": { - "type": [ "string", "null" ], - "format": "date", - "description": "The installer release date" - }, - "InstallLocationRequired": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer requires an install location provided" - }, - "RequireExplicitUpgrade": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer should be pinned by default from upgrade" - }, - "DisplayInstallWarnings": { - "type": [ "boolean", "null" ], - "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." - }, - "UnsupportedOSArchitectures": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedOSArchitecture", - "enum": [ - "x86", - "x64", - "arm", - "arm64" - ] - }, - "description": "List of OS architectures the installer does not support" - }, - "UnsupportedArguments": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedArgument", - "enum": [ - "log", - "location" - ] - }, - "description": "List of winget arguments the installer does not support" - }, - "AppsAndFeaturesEntry": { - "type": "object", - "properties": { - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The DisplayName registry value" - }, - "Publisher": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The Publisher registry value" - }, - "DisplayVersion": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 128, - "description": "The DisplayVersion registry value" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" - }, - "UpgradeCode": { - "$ref": "#/definitions/ProductCode" - }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - } - }, - "description": "Various key values under installer's ARP entry" - }, - "AppsAndFeaturesEntries": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 128, - "items": { - "$ref": "#/definitions/AppsAndFeaturesEntry" - }, - "description": "List of ARP entries." - }, - "ElevationRequirement": { - "type": [ "string", "null" ], - "enum": [ - "elevationRequired", - "elevationProhibited", - "elevatesSelf" - ], - "description": "The installer's elevation requirement" - }, - "InstallationMetadata": { - "type": "object", - "title": "InstallationMetadata", - "properties": { - "DefaultInstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Represents the default installed package location. Used for deeper installation detection." }, - "Files": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 2048, - "items": { + "Icon": { "type": "object", - "title": "InstalledFile", "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 2048, - "description": "The relative path to the installed file." - }, - "FileSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the installed file." - }, - "FileType": { - "type": [ "string", "null" ], - "enum": [ - "launch", - "uninstall", - "other" - ], - "description": "The optional installed file type. If not specified, the file is treated as other." - }, - "InvocationParameter": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Optional parameter for invocable files." - }, - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "Optional display name for invocable files." - } + "IconUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The url of the hosted icon file" + }, + "IconFileType": { + "type": "string", + "enum": [ + "png", + "jpeg", + "ico" + ], + "description": "The icon file type" + }, + "IconResolution": { + "type": [ "string", "null" ], + "enum": [ + "custom", + "16x16", + "20x20", + "24x24", + "30x30", + "32x32", + "36x36", + "40x40", + "48x48", + "60x60", + "64x64", + "72x72", + "80x80", + "96x96", + "256x256" + ], + "description": "Optional icon resolution" + }, + "IconTheme": { + "type": [ "string", "null" ], + "enum": [ + "default", + "light", + "dark", + "highContrast" + ], + "description": "Optional icon theme" + }, + "IconSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the icon file" + } }, - "required": [ "RelativeFilePath" ], - "description": "Represents an installed file." - }, - "description": "List of installed files." - } - }, - "description": "Details about the installation. Used for deeper installation detection." - }, - "DownloadCommandProhibited": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." - }, - "RepairBehavior": { - "type": [ "string", "null" ], - "enum": [ - "modify", - "uninstaller", - "installer" - ], - "description": "The repair method" - }, - "ArchiveBinariesDependOnPath": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." - }, - "Authentication": { - "type": [ "object", "null" ], - "properties": { - "AuthenticationType": { - "type": "string", - "enum": [ - "none", - "microsoftEntraId", - "microsoftEntraIdForAzureBlobStorage" - ], - "description": "The authentication type" + "required": [ + "IconUrl", + "IconFileType" + ] }, - "MicrosoftEntraIdAuthenticationInfo": { - "type": [ "object", "null" ], - "properties": { - "Resource": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The resource value for Microsoft Entra Id authentication." - }, - "Scope": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The scope value for Microsoft Entra Id authentication." - } - }, - "description": "The Microsoft Entra Id authentication info" - } - }, - "required": [ - "AuthenticationType" - ], - "description": "The authentication requirement for downloading the installer." - }, - "Installer": { - "type": "object", - "properties": { - "InstallerLocale": { - "$ref": "#/definitions/Locale" + "Channel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 16, + "description": "The distribution channel" }, "Platform": { - "$ref": "#/definitions/Platform" + "type": [ "array", "null" ], + "items": { + "title": "Platform", + "type": "string", + "enum": [ + "Windows.Desktop", + "Windows.Universal" + ] + }, + "maxItems": 2, + "uniqueItems": true, + "description": "The installer supported operating system" }, "MinimumOSVersion": { - "$ref": "#/definitions/MinimumOSVersion" - }, - "Architecture": { - "$ref": "#/definitions/Architecture" + "type": [ "string", "null" ], + "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", + "description": "The installer minimum operating system version" }, "InstallerType": { - "$ref": "#/definitions/InstallerType" + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "zip", + "inno", + "nullsoft", + "wix", + "burn", + "pwa", + "portable", + "font" + ], + "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" }, "NestedInstallerType": { - "$ref": "#/definitions/NestedInstallerType" + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "inno", + "nullsoft", + "wix", + "burn", + "portable", + "font" + ], + "description": "Enumeration of supported nested installer types contained inside an archive file" }, "NestedInstallerFiles": { - "$ref": "#/definitions/NestedInstallerFiles" - }, - "Scope": { - "$ref": "#/definitions/Scope" - }, - "InstallerUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The installer Url" + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "NestedInstallerFile", + "properties": { + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "description": "The relative path to the nested installer file" + }, + "PortableCommandAlias": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 40, + "description": "The command alias to be used for calling the package. Only applies to the nested portable package" + } + }, + "required": [ "RelativeFilePath" ], + "description": "A nested installer file contained inside an archive" + }, + "maxItems": 1024, + "description": "List of nested installer files contained inside an archive" }, - "InstallerSha256": { - "type": "string", - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Sha256 is required. Sha256 of the installer" + "Architecture": { + "type": "string", + "enum": [ + "x86", + "x64", + "arm", + "arm64", + "neutral" + ], + "description": "The installer target architecture" }, - "SignatureSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" + "Scope": { + "type": [ "string", "null" ], + "enum": [ + "user", + "machine" + ], + "description": "Scope indicates if the installer is per user or per machine" }, "InstallModes": { - "$ref": "#/definitions/InstallModes" + "type": [ "array", "null" ], + "items": { + "title": "InstallModes", + "type": "string", + "enum": [ + "interactive", + "silent", + "silentWithProgress" + ] + }, + "maxItems": 3, + "uniqueItems": true, + "description": "List of supported installer modes" }, "InstallerSwitches": { - "$ref": "#/definitions/InstallerSwitches" + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" + }, + "InstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Upgrade": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the installer by winget" + }, + "Repair": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair" + } + } + }, + "InstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the installer after execution" }, "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero installer success exit codes other than known default values by winget" + }, + "UninstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the uninstaller by winget" + } + } + }, + "UninstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the uninstaller after execution" + }, + "UninstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + }, + "ReturnResponse": { + "type": "string", + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] }, "ExpectedReturnCodes": { - "$ref": "#/definitions/ExpectedReturnCodes" + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "ExpectedReturnCode", + "properties": { + "InstallerReturnCode": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "UninstallerReturnCode": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "ReturnResponse": { + "$ref": "#/definitions/ReturnResponse" + }, + "ReturnResponseUrl": { + "$ref": "#/definitions/Url", + "description": "The return response url to provide additional guidance for expected return codes" + } + }, + "anyOf": [ + { + "required:": [ "InstallerReturnCode", "ReturnResponse" ] + }, + { + "required": [ "UninstallerReturnCode", "ReturnResponse" ] + } + ] + }, + "maxItems": 128, + "description": "Installer exit codes for common errors" }, "UpgradeBehavior": { - "$ref": "#/definitions/UpgradeBehavior" + "type": [ "string", "null" ], + "enum": [ + "install", + "uninstallPrevious", + "deny" + ], + "description": "The upgrade method" }, "Commands": { - "$ref": "#/definitions/Commands" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of commands or aliases to run the package" }, "Protocols": { - "$ref": "#/definitions/Protocols" + "type": [ "array", "null" ], + "items": { + "type": "string", + "maxLength": 2048 + }, + "maxItems": 64, + "uniqueItems": true, + "description": "List of protocols the package provides a handler for" }, "FileExtensions": { - "$ref": "#/definitions/FileExtensions" + "type": [ "array", "null" ], + "items": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 64 + }, + "maxItems": 512, + "uniqueItems": true, + "description": "List of file extensions the package could support" }, "Dependencies": { - "$ref": "#/definitions/Dependencies" + "type": [ "object", "null" ], + "properties": { + "WindowsFeatures": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows feature dependencies" + }, + "WindowsLibraries": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows library dependencies" + }, + "PackageDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "properties": { + "PackageIdentifier": { + "$ref": "#/definitions/PackageIdentifier" + }, + "MinimumVersion": { + "$ref": "#/definitions/PackageVersion" + } + }, + "required": [ "PackageIdentifier" ] + }, + "maxItems": 16, + "description": "List of package dependencies from current source" + }, + "ExternalDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of external package dependencies" + } + } }, "PackageFamilyName": { - "$ref": "#/definitions/PackageFamilyName" + "type": [ "string", "null" ], + "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", + "maxLength": 255, + "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" }, "ProductCode": { - "$ref": "#/definitions/ProductCode" + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 255, + "description": "ProductCode could be used for correlation of packages across sources" }, "Capabilities": { - "$ref": "#/definitions/Capabilities" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer capabilities" }, "RestrictedCapabilities": { - "$ref": "#/definitions/RestrictedCapabilities" + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer restricted capabilities" + }, + "Market": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "description": "The installer target market" + }, + "MarketArray": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 256, + "items": { + "$ref": "#/definitions/Market" + }, + "description": "Array of markets" }, "Markets": { - "$ref": "#/definitions/Markets" + "description": "The installer markets", + "type": [ "object", "null" ], + "oneOf": [ + { + "properties": { + "AllowedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "AllowedMarkets" ] + }, + { + "properties": { + "ExcludedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "ExcludedMarkets" ] + } + ] }, "InstallerAbortsTerminal": { - "$ref": "#/definitions/InstallerAbortsTerminal" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer will abort terminal. Default is false" }, "ReleaseDate": { - "$ref": "#/definitions/ReleaseDate" + "type": [ "string", "null" ], + "format": "date", + "description": "The installer release date" }, "InstallLocationRequired": { - "$ref": "#/definitions/InstallLocationRequired" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer requires an install location provided" }, "RequireExplicitUpgrade": { - "$ref": "#/definitions/RequireExplicitUpgrade" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer should be pinned by default from upgrade" }, "DisplayInstallWarnings": { - "$ref": "#/definitions/DisplayInstallWarnings" + "type": [ "boolean", "null" ], + "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." }, "UnsupportedOSArchitectures": { - "$ref": "#/definitions/UnsupportedOSArchitectures" + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedOSArchitecture", + "enum": [ + "x86", + "x64", + "arm", + "arm64" + ] + }, + "description": "List of OS architectures the installer does not support" }, "UnsupportedArguments": { - "$ref": "#/definitions/UnsupportedArguments" + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedArgument", + "enum": [ + "log", + "location" + ] + }, + "description": "List of winget arguments the installer does not support" + }, + "AppsAndFeaturesEntry": { + "type": "object", + "properties": { + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The DisplayName registry value" + }, + "Publisher": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The Publisher registry value" + }, + "DisplayVersion": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 128, + "description": "The DisplayVersion registry value" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "UpgradeCode": { + "$ref": "#/definitions/ProductCode" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + } + }, + "description": "Various key values under installer's ARP entry" }, "AppsAndFeaturesEntries": { - "$ref": "#/definitions/AppsAndFeaturesEntries" + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 128, + "items": { + "$ref": "#/definitions/AppsAndFeaturesEntry" + }, + "description": "List of ARP entries." }, "ElevationRequirement": { - "$ref": "#/definitions/ElevationRequirement" + "type": [ "string", "null" ], + "enum": [ + "elevationRequired", + "elevationProhibited", + "elevatesSelf" + ], + "description": "The installer's elevation requirement" }, "InstallationMetadata": { - "$ref": "#/definitions/InstallationMetadata" + "type": "object", + "title": "InstallationMetadata", + "properties": { + "DefaultInstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Represents the default installed package location. Used for deeper installation detection." + }, + "Files": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 2048, + "items": { + "type": "object", + "title": "InstalledFile", + "properties": { + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 2048, + "description": "The relative path to the installed file." + }, + "FileSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the installed file." + }, + "FileType": { + "type": [ "string", "null" ], + "enum": [ + "launch", + "uninstall", + "other" + ], + "description": "The optional installed file type. If not specified, the file is treated as other." + }, + "InvocationParameter": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Optional parameter for invocable files." + }, + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "Optional display name for invocable files." + } + }, + "required": [ "RelativeFilePath" ], + "description": "Represents an installed file." + }, + "description": "List of installed files." + } + }, + "description": "Details about the installation. Used for deeper installation detection." }, "DownloadCommandProhibited": { - "$ref": "#/definitions/DownloadCommandProhibited" + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." }, "RepairBehavior": { - "$ref": "#/definitions/RepairBehavior" + "type": [ "string", "null" ], + "enum": [ + "modify", + "uninstaller", + "installer" + ], + "description": "The repair method" }, "ArchiveBinariesDependOnPath": { - "$ref": "#/definitions/ArchiveBinariesDependOnPath" + "type": [ "boolean", "null" ], + "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." }, "Authentication": { - "$ref": "#/definitions/Authentication" + "type": [ "object", "null" ], + "properties": { + "AuthenticationType": { + "type": "string", + "enum": [ + "none", + "microsoftEntraId", + "microsoftEntraIdForAzureBlobStorage" + ], + "description": "The authentication type" + }, + "MicrosoftEntraIdAuthenticationInfo": { + "type": [ "object", "null" ], + "properties": { + "Resource": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The resource value for Microsoft Entra Id authentication." + }, + "Scope": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The scope value for Microsoft Entra Id authentication." + } + }, + "description": "The Microsoft Entra Id authentication info" + } + }, + "required": [ + "AuthenticationType" + ], + "description": "The authentication requirement for downloading the installer." + }, + "Installer": { + "type": "object", + "properties": { + "InstallerLocale": { + "$ref": "#/definitions/Locale" + }, + "Platform": { + "$ref": "#/definitions/Platform" + }, + "MinimumOSVersion": { + "$ref": "#/definitions/MinimumOSVersion" + }, + "Architecture": { + "$ref": "#/definitions/Architecture" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + }, + "NestedInstallerType": { + "$ref": "#/definitions/NestedInstallerType" + }, + "NestedInstallerFiles": { + "$ref": "#/definitions/NestedInstallerFiles" + }, + "Scope": { + "$ref": "#/definitions/Scope" + }, + "InstallerUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The installer Url" + }, + "InstallerSha256": { + "type": "string", + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Sha256 is required. Sha256 of the installer" + }, + "SignatureSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" + }, + "InstallModes": { + "$ref": "#/definitions/InstallModes" + }, + "InstallerSwitches": { + "$ref": "#/definitions/InstallerSwitches" + }, + "InstallerSuccessCodes": { + "$ref": "#/definitions/InstallerSuccessCodes" + }, + "ExpectedReturnCodes": { + "$ref": "#/definitions/ExpectedReturnCodes" + }, + "UpgradeBehavior": { + "$ref": "#/definitions/UpgradeBehavior" + }, + "Commands": { + "$ref": "#/definitions/Commands" + }, + "Protocols": { + "$ref": "#/definitions/Protocols" + }, + "FileExtensions": { + "$ref": "#/definitions/FileExtensions" + }, + "Dependencies": { + "$ref": "#/definitions/Dependencies" + }, + "PackageFamilyName": { + "$ref": "#/definitions/PackageFamilyName" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "Capabilities": { + "$ref": "#/definitions/Capabilities" + }, + "RestrictedCapabilities": { + "$ref": "#/definitions/RestrictedCapabilities" + }, + "Markets": { + "$ref": "#/definitions/Markets" + }, + "InstallerAbortsTerminal": { + "$ref": "#/definitions/InstallerAbortsTerminal" + }, + "ReleaseDate": { + "$ref": "#/definitions/ReleaseDate" + }, + "InstallLocationRequired": { + "$ref": "#/definitions/InstallLocationRequired" + }, + "RequireExplicitUpgrade": { + "$ref": "#/definitions/RequireExplicitUpgrade" + }, + "DisplayInstallWarnings": { + "$ref": "#/definitions/DisplayInstallWarnings" + }, + "UnsupportedOSArchitectures": { + "$ref": "#/definitions/UnsupportedOSArchitectures" + }, + "UnsupportedArguments": { + "$ref": "#/definitions/UnsupportedArguments" + }, + "AppsAndFeaturesEntries": { + "$ref": "#/definitions/AppsAndFeaturesEntries" + }, + "ElevationRequirement": { + "$ref": "#/definitions/ElevationRequirement" + }, + "InstallationMetadata": { + "$ref": "#/definitions/InstallationMetadata" + }, + "DownloadCommandProhibited": { + "$ref": "#/definitions/DownloadCommandProhibited" + }, + "RepairBehavior": { + "$ref": "#/definitions/RepairBehavior" + }, + "ArchiveBinariesDependOnPath": { + "$ref": "#/definitions/ArchiveBinariesDependOnPath" + }, + "Authentication": { + "$ref": "#/definitions/Authentication" + }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" + } + }, + "required": [ + "Architecture", + "InstallerUrl", + "InstallerSha256" + ] } - }, - "required": [ - "Architecture", - "InstallerUrl", - "InstallerSha256" - ] - } - }, + }, "type": "object", "properties": { "PackageIdentifier": { diff --git a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml index 91fa227d69..d6a0ad7c92 100644 --- a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml +++ b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml @@ -57,6 +57,12 @@ InstallerSwitches: InstallLocation: /dir= Upgrade: /upgrade Repair: /repair +UninstallerSwitches: + Custom: /custom + SilentWithProgress: /silentwithprogress + Silent: /silence + Interactive: /interactive + Log: /log= InstallerSuccessCodes: - 1 - 0x80070005 @@ -111,6 +117,8 @@ ExpectedReturnCodes: - InstallerReturnCode: 10 ReturnResponse: packageInUse ReturnResponseUrl: https://DefaultReturnResponseUrl.com + - UninstallerReturnCode: 2 + ReturnResponse: rebootRequiredToFinish UnsupportedArguments: - log NestedInstallerType: msi diff --git a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml index b5844cc2d9..72fc641266 100644 --- a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml +++ b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml @@ -115,6 +115,12 @@ Installers: InstallLocation: /d= Upgrade: /u Repair: /r + UninstallerSwitches: + Custom: /c + SilentWithProgress: /sp + Silent: /s + Interactive: /i + Log: /l= UpgradeBehavior: install Commands: - makemsixPreview @@ -159,6 +165,11 @@ Installers: - InstallerReturnCode: 3 ReturnResponse: custom ReturnResponseUrl: https://defaultReturnResponseUrl.com + - UninstallerReturnCode: 5 + ReturnResponse: rebootRequired + - UninstallerReturnCode: 9 + ReturnResponse: custom + ReturnResponseUrl: https://defaultReturnResponseUrl.com UnsupportedArguments: - location DownloadCommandProhibited: false @@ -170,6 +181,9 @@ Installers: ProductCode: "{Bar}" InstallerSwitches: Repair: /r + UninstallerSwitches: + Silent: /s + Custom: /foo UpgradeBehavior: deny RepairBehavior: uninstaller - Architecture: x86 diff --git a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp index 4483fbdaba..0d6c4c76af 100644 --- a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp +++ b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp @@ -75,7 +75,8 @@ namespace AppInstaller::Manifest::YamlWriter constexpr std::string_view MicrosoftEntraIdScope = "Scope"sv; // Installer switches - constexpr std::string_view InstallerSwitches = "InstallerSwitches"sv; + constexpr std::string_view InstallerSwitches = "InstallerSwitches"sv; + constexpr std::string_view UninstallerSwitches = "UninstallerSwitches"sv; constexpr std::string_view Silent = "Silent"sv; constexpr std::string_view SilentWithProgress = "SilentWithProgress"sv; constexpr std::string_view Interactive = "Interactive"sv; @@ -85,7 +86,8 @@ namespace AppInstaller::Manifest::YamlWriter constexpr std::string_view Custom = "Custom"sv; constexpr std::string_view Repair = "Repair"sv; - constexpr std::string_view InstallerSuccessCodes = "InstallerSuccessCodes"sv; + constexpr std::string_view InstallerSuccessCodes = "InstallerSuccessCodes"sv; + constexpr std::string_view UninstallerSuccessCodes = "UninstallerSuccessCodes"sv; constexpr std::string_view UpgradeBehavior = "UpgradeBehavior"sv; constexpr std::string_view Commands = "Commands"sv; constexpr std::string_view Protocols = "Protocols"sv; From c2f626a3ee292fd29d5ae4932248bba35f220df7 Mon Sep 17 00:00:00 2001 From: David Bennett Date: Sun, 21 Sep 2025 10:59:33 -0700 Subject: [PATCH 2/6] Implement Uninstaller Success Codes --- .../latest/manifest.installer.latest.json | 65 ++++++++----------- .../latest/manifest.singleton.latest.json | 65 +++++++++---------- .../Workflows/UninstallFlow.cpp | 3 +- .../RestInterface_1_12.cpp | 5 ++ .../TestData/ManifestV1_12-Singleton.yaml | 5 +- .../ManifestV1_12-MultiFile-Installer.yaml | 8 +-- .../Manifest/ManifestSchemaValidation.cpp | 3 +- .../Manifest/ManifestYamlPopulator.cpp | 1 + .../Manifest/YamlWriter.cpp | 20 +++++- .../Public/winget/ManifestCommon.h | 9 +++ .../Public/winget/ManifestInstaller.h | 4 ++ .../Schema/1_12/Json/ManifestDeserializer.h | 2 + .../1_12/Json/ManifestDeserializer_1_12.cpp | 30 +++++++++ .../ManifestUnitTest/V1ManifestReadTest.cs | 8 +++ .../TestCollateral/V1_12ManifestMerged.yaml | 3 + src/WinGetUtilInterop/Manifest/V1/Manifest.cs | 7 +- .../Manifest/V1/ManifestInstaller.cs | 7 +- 17 files changed, 158 insertions(+), 87 deletions(-) diff --git a/schemas/JSON/manifests/latest/manifest.installer.latest.json b/schemas/JSON/manifests/latest/manifest.installer.latest.json index c902789a5c..cfc7a7a7d8 100644 --- a/schemas/JSON/manifests/latest/manifest.installer.latest.json +++ b/schemas/JSON/manifests/latest/manifest.installer.latest.json @@ -271,30 +271,6 @@ "uniqueItems": true, "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" }, - "ReturnResponse": { - "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, "ExpectedReturnCodes": { "type": [ "array", "null" ], "items": { @@ -304,25 +280,36 @@ "InstallerReturnCode": { "$ref": "#/definitions/InstallerReturnCode" }, - "UninstallerReturnCode": { - "$ref": "#/definitions/UninstallerReturnCode" - }, "ReturnResponse": { - "$ref": "#/definitions/ReturnResponse" + "type": "string", + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] }, "ReturnResponseUrl": { "$ref": "#/definitions/Url", "description": "The return response url to provide additional guidance for expected return codes" } }, - "anyOf": [ - { - "required:": [ "InstallerReturnCode", "ReturnResponse" ] - }, - { - "required": [ "UninstallerReturnCode", "ReturnResponse" ] - } - ] + "required": [ "InstallerReturnCode", "ReturnResponse" ] }, "maxItems": 128, "description": "Installer exit codes for common errors" @@ -886,13 +873,13 @@ "$ref": "#/definitions/InstallerSwitches" }, "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" + "$ref": "#/definitions/InstallerSuccessCodes" }, "UninstallerSwitches": { - "$ref": "#/definitions/UninstallerSwitches" + "$ref": "#/definitions/UninstallerSwitches" }, "UninstallerSuccessCodes": { - "$ref": "#/definitions/UninstallerSuccessCodes" + "$ref": "#/definitions/UninstallerSuccessCodes" }, "ExpectedReturnCodes": { "$ref": "#/definitions/ExpectedReturnCodes" diff --git a/schemas/JSON/manifests/latest/manifest.singleton.latest.json b/schemas/JSON/manifests/latest/manifest.singleton.latest.json index 4d4b89ea80..b2c1fada56 100644 --- a/schemas/JSON/manifests/latest/manifest.singleton.latest.json +++ b/schemas/JSON/manifests/latest/manifest.singleton.latest.json @@ -373,30 +373,6 @@ "uniqueItems": true, "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" }, - "ReturnResponse": { - "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, "ExpectedReturnCodes": { "type": [ "array", "null" ], "items": { @@ -406,25 +382,36 @@ "InstallerReturnCode": { "$ref": "#/definitions/InstallerReturnCode" }, - "UninstallerReturnCode": { - "$ref": "#/definitions/UninstallerReturnCode" - }, "ReturnResponse": { - "$ref": "#/definitions/ReturnResponse" + "type": "string", + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] }, "ReturnResponseUrl": { "$ref": "#/definitions/Url", "description": "The return response url to provide additional guidance for expected return codes" } }, - "anyOf": [ - { - "required:": [ "InstallerReturnCode", "ReturnResponse" ] - }, - { - "required": [ "UninstallerReturnCode", "ReturnResponse" ] - } - ] + "required": [ "InstallerReturnCode", "ReturnResponse" ] }, "maxItems": 128, "description": "Installer exit codes for common errors" @@ -1112,6 +1099,12 @@ "InstallerSuccessCodes": { "$ref": "#/definitions/InstallerSuccessCodes" }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" + }, "ExpectedReturnCodes": { "$ref": "#/definitions/ExpectedReturnCodes" }, diff --git a/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp b/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp index ce12427900..46a6afe491 100644 --- a/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp @@ -428,7 +428,8 @@ namespace AppInstaller::CLI::Workflow void ReportUninstallerResult::operator()(Execution::Context& context) const { DWORD uninstallResult = context.Get(); - if (uninstallResult != 0) + const auto& additionalSuccessCodes = context.Get()->UninstallerSuccessCodes; + if (uninstallResult != 0 && (std::find(additionalSuccessCodes.begin(), additionalSuccessCodes.end(), uninstallResult) == additionalSuccessCodes.end())) { const auto installedPackageVersion = context.Get(); Logging::Telemetry().LogUninstallerFailure( diff --git a/src/AppInstallerCLITests/RestInterface_1_12.cpp b/src/AppInstallerCLITests/RestInterface_1_12.cpp index fb55136924..b4c7dc5859 100644 --- a/src/AppInstallerCLITests/RestInterface_1_12.cpp +++ b/src/AppInstallerCLITests/RestInterface_1_12.cpp @@ -147,6 +147,9 @@ namespace "InstallerSuccessCodes": [ 0 ], + "UninstallerSuccessCodes": [ + 1 + ], "UpgradeBehavior": "deny", "Commands": [ "command1" @@ -337,6 +340,8 @@ namespace REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == "/repair"); REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1); REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0); + REQUIRE(actualInstaller.UninstallerSuccessCodes.size() == 1); + REQUIRE(actualInstaller.UninstallerSuccessCodes.at(0) == 1); REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny); REQUIRE(actualInstaller.Commands.at(0) == "command1"); REQUIRE(actualInstaller.Protocols.at(0) == "protocol1"); diff --git a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml index d6a0ad7c92..72c6c10654 100644 --- a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml +++ b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml @@ -66,6 +66,9 @@ UninstallerSwitches: InstallerSuccessCodes: - 1 - 0x80070005 +UninstallerSuccessCodes: + - 2 + - 0x80070002 UpgradeBehavior: uninstallPrevious RepairBehavior: modify Commands: @@ -117,8 +120,6 @@ ExpectedReturnCodes: - InstallerReturnCode: 10 ReturnResponse: packageInUse ReturnResponseUrl: https://DefaultReturnResponseUrl.com - - UninstallerReturnCode: 2 - ReturnResponse: rebootRequiredToFinish UnsupportedArguments: - log NestedInstallerType: msi diff --git a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml index 72fc641266..e0f66b5e43 100644 --- a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml +++ b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml @@ -25,6 +25,9 @@ InstallerSwitches: InstallerSuccessCodes: - 1 - 0x80070005 +UninstallerSuccessCodes: + - 2 + - 0x80070002 UpgradeBehavior: uninstallPrevious RepairBehavior: modify Commands: @@ -165,11 +168,6 @@ Installers: - InstallerReturnCode: 3 ReturnResponse: custom ReturnResponseUrl: https://defaultReturnResponseUrl.com - - UninstallerReturnCode: 5 - ReturnResponse: rebootRequired - - UninstallerReturnCode: 9 - ReturnResponse: custom - ReturnResponseUrl: https://defaultReturnResponseUrl.com UnsupportedArguments: - location DownloadCommandProhibited: false diff --git a/src/AppInstallerCommonCore/Manifest/ManifestSchemaValidation.cpp b/src/AppInstallerCommonCore/Manifest/ManifestSchemaValidation.cpp index 54ff6bbdb8..fb26df8ff7 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestSchemaValidation.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestSchemaValidation.cpp @@ -33,7 +33,8 @@ namespace AppInstaller::Manifest::YamlParser { "DisplayInstallWarnings"sv, YamlScalarType::Bool }, { "InstallerReturnCode"sv, YamlScalarType::Int }, { "DownloadCommandProhibited", YamlScalarType::Bool }, - { "ArchiveBinariesDependOnPath", YamlScalarType::Bool } + { "ArchiveBinariesDependOnPath", YamlScalarType::Bool }, + { "UninstallerSuccessCodes"sv, YamlScalarType::Int }, }; YamlScalarType GetManifestScalarValueType(const std::string& key) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 2d46f60403..0bca86f1f7 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -297,6 +297,7 @@ namespace AppInstaller::Manifest { "Dependencies", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, DependenciesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Dependencies))); }}, { "Capabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Capabilities = ProcessStringSequenceNode(value); return {}; } }, { "RestrictedCapabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, + { "UninstallerSuccessCodes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UninstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); diff --git a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp index 0d6c4c76af..b24085054b 100644 --- a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp +++ b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp @@ -432,6 +432,23 @@ namespace AppInstaller::Manifest::YamlWriter } out << YAML::EndSeq; } + + + void ProcessUninstallerSuccessCodes(YAML::Emitter& out, const std::vector& uninstallerSuccessCodes) + { + if (uninstallerSuccessCodes.empty()) + { + return; + } + + out << YAML::Key << UninstallerSuccessCodes; + out << YAML::BeginSeq; + for (auto const& uninstallerSuccessCode : uninstallerSuccessCodes) + { + out << std::to_string(uninstallerSuccessCode); + } + out << YAML::EndSeq; + } void ProcessMarkets(YAML::Emitter& out, const MarketsInfo& marketsInfo) { @@ -633,7 +650,8 @@ namespace AppInstaller::Manifest::YamlWriter ProcessPlatforms(out, installer.Platform); ProcessUnsupportedArguments(out, installer.UnsupportedArguments); ProcessUnsupportedOSArchitecture(out, installer.UnsupportedOSArchitectures); - ProcessAuthentication(out, installer.AuthInfo); + ProcessAuthentication(out, installer.AuthInfo); + ProcessUninstallerSuccessCodes(out, installer.UninstallerSuccessCodes); } void ProcessInstaller(YAML::Emitter& out, const ManifestInstaller& installer) diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h index f987b7705d..7ddba18a90 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h @@ -128,6 +128,15 @@ namespace AppInstaller::Manifest Repair, }; + enum class UninstallerSwitchType + { + Custom, + Silent, + SilentWithProgress, + Interactive, + Log, + }; + enum class RepairBehaviorEnum { Unknown, diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestInstaller.h b/src/AppInstallerCommonCore/Public/winget/ManifestInstaller.h index 9812933410..31ccbe8844 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestInstaller.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestInstaller.h @@ -61,6 +61,10 @@ namespace AppInstaller::Manifest std::vector InstallerSuccessCodes; + std::map UninstallerSwitches; + + std::vector UninstallerSuccessCodes; + struct ExpectedReturnCodeInfo { ExpectedReturnCodeEnum ReturnResponseEnum = ExpectedReturnCodeEnum::Unknown; diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h index eeffe76067..cb059d6046 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h @@ -10,6 +10,8 @@ namespace AppInstaller::Repository::Rest::Schema::V1_12::Json { protected: + std::optional DeserializeInstaller(const web::json::value& installerJsonObject) const override; + Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override; Manifest::ManifestVer GetManifestVersion() const override; diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp index a4a0beeec3..1e5dd17f17 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp @@ -9,6 +9,36 @@ using namespace AppInstaller::Manifest; namespace AppInstaller::Repository::Rest::Schema::V1_12::Json { + constexpr std::string_view UninstallerSuccessCodes = "UninstallerSuccessCodes"sv; + + std::optional ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const + { + auto result = V1_10::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject); + + if (result) + { + auto& installer = result.value(); + + installer.AuthInfo = ParseAuthenticationInfo(installerJsonObject, ParseAuthenticationInfoType::Installer, GetManifestVersion()); + + // Uninstaller SuccessCodes + std::optional> uninstallSuccessCodes = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(UninstallerSuccessCodes)); + if (uninstallSuccessCodes) + { + for (auto& code : uninstallSuccessCodes.value().get()) + { + std::optional codeValue = JSON::GetRawIntValueFromJsonValue(code); + if (codeValue) + { + installer.UninstallerSuccessCodes.emplace_back(std::move(codeValue.value())); + } + } + } + } + + return result; + } + Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const { std::string inStrLower = Utility::ToLower(in); diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 1c3eefaca4..e837ba5a95 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -197,6 +197,14 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal(2, manifest.InstallerSuccessCodes.Count); Assert.Equal(1, manifest.InstallerSuccessCodes[0]); Assert.Equal(0x80070005, manifest.InstallerSuccessCodes[1]); + + if (manifestVersion >= TestManifestVersion.V1_12_0) + { + Assert.Equal(2, manifest.UninstallerSuccessCodes.Count); + Assert.Equal(2, manifest.UninstallerSuccessCodes[0]); + Assert.Equal(0x80070002, manifest.UninstallerSuccessCodes[1]); + } + Assert.Equal("uninstallPrevious", manifest.UpgradeBehavior); Assert.Equal(2, manifest.Commands.Count); Assert.Equal("makemsix", manifest.Commands[0]); diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml index dd92b92ab9..6cf4c3af29 100644 --- a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml @@ -58,6 +58,9 @@ InstallerSwitches: InstallerSuccessCodes: - 1 - 0x80070005 +UninstallerSuccessCodes: + - 2 + - 0x80070002 UpgradeBehavior: uninstallPrevious Commands: - makemsix diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs index 9df3343f84..0ac9a4a5f1 100644 --- a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs +++ b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -196,7 +196,12 @@ public class Manifest /// /// Gets or sets the default list of additional installer success codes. /// - public List InstallerSuccessCodes { get; set; } + public List InstallerSuccessCodes { get; set; } + + /// + /// Gets or sets the default list of additional installer success codes. + /// + public List UninstallerSuccessCodes { get; set; } /// /// Gets or sets the default upgrade behavior. diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs index 172bb0de58..0a0517ade1 100644 --- a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs +++ b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs @@ -78,7 +78,12 @@ public class ManifestInstaller /// /// Gets or sets the list of additional installer success codes. /// - public List InstallerSuccessCodes { get; set; } + public List InstallerSuccessCodes { get; set; } + + /// + /// Gets or sets the list of additional installer success codes. + /// + public List UninstallerSuccessCodes { get; set; } /// /// Gets or sets the upgrade behavior. From b3c68f7cc24a0db244d3f2d57dbd2437d8c9fb7e Mon Sep 17 00:00:00 2001 From: David Bennett Date: Mon, 22 Sep 2025 01:03:36 -0700 Subject: [PATCH 3/6] Add Uninstallerswitches schema --- .../RestInterface_1_12.cpp | 13 ++ .../TestData/ManifestV1_12-Singleton.yaml | 6 + .../ManifestV1_12-MultiFile-Installer.yaml | 6 + src/AppInstallerCLITests/YamlManifest.cpp | 20 +++ .../Manifest/ManifestCommon.cpp | 19 +++ .../Manifest/ManifestYamlPopulator.cpp | 34 ++++- .../Manifest/YamlWriter.cpp | 17 +++ .../Public/winget/ManifestCommon.h | 2 + .../Public/winget/ManifestYamlPopulator.h | 4 +- .../Schema/1_12/Json/ManifestDeserializer.h | 2 + .../1_12/Json/ManifestDeserializer_1_12.cpp | 49 +++++++- .../ManifestUnitTest/V1ManifestReadTest.cs | 17 +++ .../TestCollateral/V1_12ManifestMerged.yaml | 12 ++ src/WinGetUtilInterop/Manifest/V1/Manifest.cs | 7 +- .../Manifest/V1/ManifestInstaller.cs | 15 ++- .../Manifest/V1/UninstallerSwitches.cs | 119 ++++++++++++++++++ 16 files changed, 333 insertions(+), 9 deletions(-) create mode 100644 src/WinGetUtilInterop/Manifest/V1/UninstallerSwitches.cs diff --git a/src/AppInstallerCLITests/RestInterface_1_12.cpp b/src/AppInstallerCLITests/RestInterface_1_12.cpp index b4c7dc5859..f67922a695 100644 --- a/src/AppInstallerCLITests/RestInterface_1_12.cpp +++ b/src/AppInstallerCLITests/RestInterface_1_12.cpp @@ -147,6 +147,13 @@ namespace "InstallerSuccessCodes": [ 0 ], + "UninstallerSwitches": { + "Silent": "/s", + "SilentWithProgress": "/s", + "Interactive": "/i", + "Log": "/l", + "Custom": "/custom" + }, "UninstallerSuccessCodes": [ 1 ], @@ -340,6 +347,12 @@ namespace REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == "/repair"); REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1); REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0); + REQUIRE(actualInstaller.UninstallerSwitches.size() == 5); + REQUIRE(actualInstaller.UninstallerSwitches.at(UninstallerSwitchType::Silent) == "/s"); + REQUIRE(actualInstaller.UninstallerSwitches.at(UninstallerSwitchType::SilentWithProgress) == "/s"); + REQUIRE(actualInstaller.UninstallerSwitches.at(UninstallerSwitchType::Interactive) == "/i"); + REQUIRE(actualInstaller.UninstallerSwitches.at(UninstallerSwitchType::Log) == "/l"); + REQUIRE(actualInstaller.UninstallerSwitches.at(UninstallerSwitchType::Custom) == "/custom"); REQUIRE(actualInstaller.UninstallerSuccessCodes.size() == 1); REQUIRE(actualInstaller.UninstallerSuccessCodes.at(0) == 1); REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny); diff --git a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml index 72c6c10654..9541e567bd 100644 --- a/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml +++ b/src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml @@ -159,6 +159,12 @@ Installers: InstallLocation: /d= Upgrade: /u Repair: /r + UninstallerSwitches: + Custom: /c + SilentWithProgress: /sp + Silent: /s + Interactive: /i + Log: /l= UpgradeBehavior: install Commands: - makemsixPreview diff --git a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml index e0f66b5e43..f7ffeec21c 100644 --- a/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml +++ b/src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml @@ -22,6 +22,12 @@ InstallerSwitches: InstallLocation: /dir= Upgrade: /upgrade Repair: /repair +UninstallerSwitches: + Custom: /custom + SilentWithProgress: /silentwithprogress + Silent: /silence + Interactive: /interactive + Log: /log= InstallerSuccessCodes: - 1 - 0x80070005 diff --git a/src/AppInstallerCLITests/YamlManifest.cpp b/src/AppInstallerCLITests/YamlManifest.cpp index ce1b23b757..18ce5f63fa 100644 --- a/src/AppInstallerCLITests/YamlManifest.cpp +++ b/src/AppInstallerCLITests/YamlManifest.cpp @@ -266,6 +266,16 @@ namespace { REQUIRE(manifest.DefaultInstallerInfo.ArchiveBinariesDependOnPath); } + + if (manifestVer >= ManifestVer{ s_ManifestVersionV1_12 }) + { + auto defaultUninstallerSwitches = manifest.DefaultInstallerInfo.UninstallerSwitches; + REQUIRE(defaultUninstallerSwitches.at(UninstallerSwitchType::Custom) == "/custom"); + REQUIRE(defaultUninstallerSwitches.at(UninstallerSwitchType::SilentWithProgress) == "/silentwithprogress"); + REQUIRE(defaultUninstallerSwitches.at(UninstallerSwitchType::Silent) == "/silence"); + REQUIRE(defaultUninstallerSwitches.at(UninstallerSwitchType::Interactive) == "/interactive"); + REQUIRE(defaultUninstallerSwitches.at(UninstallerSwitchType::Log) == "/log="); + } } if (isSingleton || isExported) @@ -384,6 +394,16 @@ namespace REQUIRE(installer1.RepairBehavior == RepairBehaviorEnum::Modify); } + if (manifestVer >= ManifestVer{ s_ManifestVersionV1_12 }) + { + auto installer1UninstallSwitches = installer1.UninstallerSwitches; + REQUIRE(installer1UninstallSwitches.at(UninstallerSwitchType::Custom) == "/c"); + REQUIRE(installer1UninstallSwitches.at(UninstallerSwitchType::SilentWithProgress) == "/sp"); + REQUIRE(installer1UninstallSwitches.at(UninstallerSwitchType::Silent) == "/s"); + REQUIRE(installer1UninstallSwitches.at(UninstallerSwitchType::Interactive) == "/i"); + REQUIRE(installer1UninstallSwitches.at(UninstallerSwitchType::Log) == "/l="); + } + if (manifestVer >= ManifestVer{ s_ManifestVersionV1_9 }) { REQUIRE_FALSE(installer1.ArchiveBinariesDependOnPath); diff --git a/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp b/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp index 491d165722..aa4bac71c8 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp @@ -621,6 +621,25 @@ namespace AppInstaller::Manifest return "Unknown"sv; } + std::string_view UninstallerSwitchTypeToString(UninstallerSwitchType uninstallerSwitchType) + { + switch (uninstallerSwitchType) + { + case UninstallerSwitchType::Custom: + return "Custom"sv; + case UninstallerSwitchType::Silent: + return "Silent"sv; + case UninstallerSwitchType::SilentWithProgress: + return "SilentWithProgress"sv; + case UninstallerSwitchType::Interactive: + return "Interactive"sv; + case UninstallerSwitchType::Log: + return "Log"sv; + } + + return "Unknown"sv; + } + std::string_view ElevationRequirementToString(ElevationRequirementEnum elevationRequirement) { switch (elevationRequirement) diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 0bca86f1f7..092ff5c813 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -297,7 +297,6 @@ namespace AppInstaller::Manifest { "Dependencies", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, DependenciesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Dependencies))); }}, { "Capabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Capabilities = ProcessStringSequenceNode(value); return {}; } }, { "RestrictedCapabilities", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } }, - { "UninstallerSuccessCodes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UninstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, }; std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end())); @@ -399,6 +398,17 @@ namespace AppInstaller::Manifest std::move(fields_v1_10.begin(), fields_v1_10.end(), std::inserter(result, result.end())); } + + if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_12 }) + { + std::vector fields_v1_12 = + { + { "UninstallerSwitches", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, UninstallerSwitchesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->UninstallerSwitches))); }}, + { "UninstallerSuccessCodes", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UninstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } }, + }; + + std::move(fields_v1_12.begin(), fields_v1_12.end(), std::inserter(result, result.end())); + } } return result; @@ -437,6 +447,27 @@ namespace AppInstaller::Manifest return result; } + std::vector ManifestYamlPopulator::GetUninstallerSwitchesFieldProcessInfo() + { + std::vector result = {}; + + if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_12 }) + { + std::vector uninstallerSwitches_v1_12 = + { + { "Custom", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[UninstallerSwitchType::Custom] = value.as(); return{}; } }, + { "Silent", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[UninstallerSwitchType::Silent] = value.as(); return{}; } }, + { "SilentWithProgress", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[UninstallerSwitchType::SilentWithProgress] = value.as(); return{}; } }, + { "Interactive", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[UninstallerSwitchType::Interactive] = value.as(); return{}; } }, + { "Log", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr>(v))[UninstallerSwitchType::Log] = value.as(); return{}; } }, + }; + + std::move(uninstallerSwitches_v1_12.begin(), uninstallerSwitches_v1_12.end(), std::inserter(result, result.end())); + } + + return result; + } + std::vector ManifestYamlPopulator::GetExpectedReturnCodesFieldProcessInfo() { std::vector result = {}; @@ -1101,6 +1132,7 @@ namespace AppInstaller::Manifest RootFieldInfos = GetRootFieldProcessInfo(); InstallerFieldInfos = GetInstallerFieldProcessInfo(); SwitchesFieldInfos = GetSwitchesFieldProcessInfo(); + UninstallerSwitchesFieldInfos = GetUninstallerSwitchesFieldProcessInfo(); ExpectedReturnCodesFieldInfos = GetExpectedReturnCodesFieldProcessInfo(); DependenciesFieldInfos = GetDependenciesFieldProcessInfo(); PackageDependenciesFieldInfos = GetPackageDependenciesFieldProcessInfo(); diff --git a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp index b24085054b..1853c7f0b1 100644 --- a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp +++ b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp @@ -320,6 +320,22 @@ namespace AppInstaller::Manifest::YamlWriter WRITE_PROPERTY_IF_EXISTS(out, InstallerSwitchTypeToString(type), value); } out << YAML::EndMap; + } + + void ProcessUninstallerSwitches(YAML::Emitter& out, const std::map& uninstallerSwitches) + { + if (uninstallerSwitches.empty()) + { + return; + } + + out << YAML::Key << UninstallerSwitches; + out << YAML::BeginMap; + for (auto const& [type, value] : uninstallerSwitches) + { + WRITE_PROPERTY_IF_EXISTS(out, UninstallerSwitchTypeToString(type), value); + } + out << YAML::EndMap; } void ProcessExpectedReturnCodes(YAML::Emitter& out, const std::map& expectedReturnCodes) @@ -651,6 +667,7 @@ namespace AppInstaller::Manifest::YamlWriter ProcessUnsupportedArguments(out, installer.UnsupportedArguments); ProcessUnsupportedOSArchitecture(out, installer.UnsupportedOSArchitectures); ProcessAuthentication(out, installer.AuthInfo); + ProcessUninstallerSwitches(out, installer.UninstallerSwitches); ProcessUninstallerSuccessCodes(out, installer.UninstallerSuccessCodes); } diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h index 7ddba18a90..36d4e64fe2 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h @@ -413,6 +413,8 @@ namespace AppInstaller::Manifest std::string_view InstallerSwitchTypeToString(InstallerSwitchType installerSwitchType); + std::string_view UninstallerSwitchTypeToString(UninstallerSwitchType uninstallerSwitchType); + std::string_view ElevationRequirementToString(ElevationRequirementEnum elevationRequirement); std::string_view InstallModeToString(InstallModeEnum installMode); diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h index db7775afe2..e2c2be39a7 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h @@ -8,7 +8,7 @@ namespace AppInstaller::Manifest { // Add here new manifest pointer types. - using VariantManifestPtr = std::variant*, AppInstaller::Authentication::AuthenticationInfo*, AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo*>; + using VariantManifestPtr = std::variant*, AppInstaller::Authentication::AuthenticationInfo*, AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo*, std::map*>; struct ManifestYamlPopulator { @@ -43,6 +43,7 @@ namespace AppInstaller::Manifest std::vector RootFieldInfos; std::vector InstallerFieldInfos; std::vector SwitchesFieldInfos; + std::vector UninstallerSwitchesFieldInfos; std::vector ExpectedReturnCodesFieldInfos; std::vector DependenciesFieldInfos; std::vector PackageDependenciesFieldInfos; @@ -65,6 +66,7 @@ namespace AppInstaller::Manifest std::vector GetRootFieldProcessInfo(); std::vector GetInstallerFieldProcessInfo(bool forRootFields = false); std::vector GetSwitchesFieldProcessInfo(); + std::vector GetUninstallerSwitchesFieldProcessInfo(); std::vector GetExpectedReturnCodesFieldProcessInfo(); std::vector GetDependenciesFieldProcessInfo(); std::vector GetPackageDependenciesFieldProcessInfo(); diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h index cb059d6046..30d3d3487d 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h @@ -10,6 +10,8 @@ namespace AppInstaller::Repository::Rest::Schema::V1_12::Json { protected: + virtual std::map DeserializeUninstallerSwitches(const web::json::value& uninstallerSwitchesJsonObject) const; + std::optional DeserializeInstaller(const web::json::value& installerJsonObject) const override; Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override; diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp index 1e5dd17f17..2d4980842e 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp @@ -9,7 +9,46 @@ using namespace AppInstaller::Manifest; namespace AppInstaller::Repository::Rest::Schema::V1_12::Json { - constexpr std::string_view UninstallerSuccessCodes = "UninstallerSuccessCodes"sv; + namespace + { + // Uninstaller switches + constexpr std::string_view UninstallerSwitches = "UninstallerSwitches"sv; + constexpr std::string_view Silent = "Silent"sv; + constexpr std::string_view SilentWithProgress = "SilentWithProgress"sv; + constexpr std::string_view Interactive = "Interactive"sv; + constexpr std::string_view Log = "Log"sv; + constexpr std::string_view Custom = "Custom"sv; + + // Uninstaller Success Codes + constexpr std::string_view UninstallerSuccessCodes = "UninstallerSuccessCodes"sv; + + void TryParseUninstallerSwitchField( + std::map& uninstallerSwitches, + UninstallerSwitchType switchType, + const web::json::value& switchesJsonObject, + std::string_view switchJsonFieldName) + { + auto value = JSON::GetRawStringValueFromJsonNode(switchesJsonObject, JSON::GetUtilityString(switchJsonFieldName)); + + if (JSON::IsValidNonEmptyStringValue(value)) + { + uninstallerSwitches[switchType] = value.value(); + } + } + } + + std::map ManifestDeserializer::DeserializeUninstallerSwitches(const web::json::value& uninstallerSwitchesJsonObject) const + { + std::map uninstallerSwitches; + + TryParseUninstallerSwitchField(uninstallerSwitches, UninstallerSwitchType::Silent, uninstallerSwitchesJsonObject, Silent); + TryParseUninstallerSwitchField(uninstallerSwitches, UninstallerSwitchType::SilentWithProgress, uninstallerSwitchesJsonObject, SilentWithProgress); + TryParseUninstallerSwitchField(uninstallerSwitches, UninstallerSwitchType::Interactive, uninstallerSwitchesJsonObject, Interactive); + TryParseUninstallerSwitchField(uninstallerSwitches, UninstallerSwitchType::Log, uninstallerSwitchesJsonObject, Log); + TryParseUninstallerSwitchField(uninstallerSwitches, UninstallerSwitchType::Custom, uninstallerSwitchesJsonObject, Custom); + + return uninstallerSwitches; + } std::optional ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const { @@ -19,7 +58,13 @@ namespace AppInstaller::Repository::Rest::Schema::V1_12::Json { auto& installer = result.value(); - installer.AuthInfo = ParseAuthenticationInfo(installerJsonObject, ParseAuthenticationInfoType::Installer, GetManifestVersion()); + // Uninstaller Switches + std::optional> uninstallerSwitches = + JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(UninstallerSwitches)); + if (uninstallerSwitches) + { + installer.UninstallerSwitches = DeserializeUninstallerSwitches(uninstallerSwitches.value().get()); + } // Uninstaller SuccessCodes std::optional> uninstallSuccessCodes = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(UninstallerSuccessCodes)); diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index e837ba5a95..59596d4c36 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -200,6 +200,13 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif if (manifestVersion >= TestManifestVersion.V1_12_0) { + var defaultUninstallerSwitches = manifest.UninstallerSwitches; + Assert.Equal("/custom", defaultUninstallerSwitches.Custom); + Assert.Equal("/silentwithprogress", defaultUninstallerSwitches.SilentWithProgress); + Assert.Equal("/silence", defaultUninstallerSwitches.Silent); + Assert.Equal("/interactive", defaultUninstallerSwitches.Interactive); + Assert.Equal("/log=", defaultUninstallerSwitches.Log); + Assert.Equal(2, manifest.UninstallerSuccessCodes.Count); Assert.Equal(2, manifest.UninstallerSuccessCodes[0]); Assert.Equal(0x80070002, manifest.UninstallerSuccessCodes[1]); @@ -433,6 +440,16 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("Scope", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope); } + if (manifestVersion >= TestManifestVersion.V1_12_0) + { + var installer1UninstallerSwitches = installer1.UninstallerSwitches; + Assert.Equal("/c", installer1UninstallerSwitches.Custom); + Assert.Equal("/sp", installer1UninstallerSwitches.SilentWithProgress); + Assert.Equal("/s", installer1UninstallerSwitches.Silent); + Assert.Equal("/i", installer1UninstallerSwitches.Interactive); + Assert.Equal("/l=", installer1UninstallerSwitches.Log); + } + // Additional Localizations Assert.Single(manifest.Localization); ManifestLocalization localization1 = manifest.Localization[0]; diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml index 6cf4c3af29..d695c91398 100644 --- a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_12ManifestMerged.yaml @@ -55,6 +55,12 @@ InstallerSwitches: InstallLocation: /dir= Upgrade: /upgrade Repair: /repair +UninstallerSwitches: + Custom: /custom + SilentWithProgress: /silentwithprogress + Silent: /silence + Interactive: /interactive + Log: /log= InstallerSuccessCodes: - 1 - 0x80070005 @@ -192,6 +198,12 @@ Installers: InstallLocation: /d= Upgrade: /u Repair: /r + UninstallerSwitches: + Custom: /c + SilentWithProgress: /sp + Silent: /s + Interactive: /i + Log: /l= UpgradeBehavior: install Commands: - makemsixPreview diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs index 0ac9a4a5f1..012dfeb905 100644 --- a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs +++ b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -252,7 +252,12 @@ public class Manifest /// Gets or sets the default installer switches. /// [YamlMember(Alias = "InstallerSwitches")] - public InstallerSwitches Switches { get; set; } + public InstallerSwitches Switches { get; set; } + + /// + /// Gets or sets UninstallerSwitches. + /// + public UninstallerSwitches UninstallerSwitches { get; set; } /// /// Gets or sets the default installer markets info. diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs index 0a0517ade1..3df4a45459 100644 --- a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs +++ b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs @@ -81,7 +81,7 @@ public class ManifestInstaller public List InstallerSuccessCodes { get; set; } /// - /// Gets or sets the list of additional installer success codes. + /// Gets or sets the list of additional uninstaller success codes. /// public List UninstallerSuccessCodes { get; set; } @@ -134,7 +134,12 @@ public class ManifestInstaller /// Gets or sets the installer switches. If present, has more precedence than root. /// [YamlMember(Alias = "InstallerSwitches")] - public InstallerSwitches Switches { get; set; } + public InstallerSwitches Switches { get; set; } + + /// + /// Gets or sets UninstallerSwitches. + /// + public UninstallerSwitches UninstallerSwitches { get; set; } /// /// Gets or sets the installer markets info. @@ -283,7 +288,8 @@ public bool Equals(ManifestInstaller other) (this.InstallerLocale == other.InstallerLocale) && (this.Scope == other.Scope) && (this.InstallerType == other.InstallerType) && - (this.Switches == other.Switches) && + (this.Switches == other.Switches) && + (this.UninstallerSwitches == other.UninstallerSwitches) && (this.NestedInstallerType == other.NestedInstallerType) && (this.NestedInstallerFiles == other.NestedInstallerFiles); } @@ -301,7 +307,8 @@ public override int GetHashCode() this.InstallerLocale, this.Scope, this.InstallerType, - this.Switches, + this.Switches, + this.UninstallerSwitches, this.NestedInstallerType, this.NestedInstallerFiles).GetHashCode(); } diff --git a/src/WinGetUtilInterop/Manifest/V1/UninstallerSwitches.cs b/src/WinGetUtilInterop/Manifest/V1/UninstallerSwitches.cs new file mode 100644 index 0000000000..5273ac79b0 --- /dev/null +++ b/src/WinGetUtilInterop/Manifest/V1/UninstallerSwitches.cs @@ -0,0 +1,119 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + using System; + + /// + /// Class that contains different types of uninstaller switches like Custom, Silent and Interactive. + /// + public class UninstallerSwitches : IEquatable + { + /// + /// Gets or sets the Custom installer switch. + /// + public string Custom { get; set; } + + /// + /// Gets or sets the Silent installer switch. + /// + public string Silent { get; set; } + + /// + /// Gets or sets the SilentWithProgress installer switch. + /// + public string SilentWithProgress { get; set; } + + /// + /// Gets or sets the Interactive installer switch. + /// + public string Interactive { get; set; } + + /// + /// Gets or sets the Log installer switch. + /// + public string Log { get; set; } + + /// + /// Override op_Equality. + /// + /// left hand side. + /// right hand side. + /// boolean indicating if the objects are equals. + public static bool operator ==(UninstallerSwitches lhs, UninstallerSwitches rhs) + { + return Equals(lhs, rhs); + } + + /// + /// Override op_Inequality. + /// + /// left hand side. + /// right hand side. + /// boolean indicating if the objects are not equals. + public static bool operator !=(UninstallerSwitches lhs, UninstallerSwitches rhs) + { + return !Equals(lhs, rhs); + } + + /// + /// Override object.Equals. + /// + /// other object. + /// boolean indicating if the objects are equals. + public override bool Equals(object other) + { + return (other is UninstallerSwitches) && this.Equals(other as UninstallerSwitches); + } + + /// + /// Implemented IEquitable. + /// + /// other object. + /// boolean indicating if the objects are equals. + public bool Equals(UninstallerSwitches other) + { + // If parameter is null, return false. + if (ReferenceEquals(other, null)) + { + return false; + } + + // Optimization for a common success case. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If run-time types are not exactly the same, return false. + if (this.GetType() != other.GetType()) + { + return false; + } + + return (this.Custom == other.Custom) && + (this.Silent == other.Silent) && + (this.SilentWithProgress == other.SilentWithProgress) && + (this.Interactive == other.Interactive) && + (this.Log == other.Log); + } + + /// + /// Override object.GetHashCode. Implement if needed. + /// to create the hash. + /// + /// resulting hash. + public override int GetHashCode() + { + return (this.Custom, + this.Silent, + this.SilentWithProgress, + this.Interactive, + this.Log).GetHashCode(); + } + } +} From 8c546d9834ad67a94d8ee696472d5827f9c8a378 Mon Sep 17 00:00:00 2001 From: David Bennett Date: Mon, 22 Sep 2025 10:47:34 -0700 Subject: [PATCH 4/6] Remove success code usage until after manifest retrieval is in --- src/AppInstallerCLICore/Workflows/UninstallFlow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp b/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp index 46a6afe491..ce12427900 100644 --- a/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/UninstallFlow.cpp @@ -428,8 +428,7 @@ namespace AppInstaller::CLI::Workflow void ReportUninstallerResult::operator()(Execution::Context& context) const { DWORD uninstallResult = context.Get(); - const auto& additionalSuccessCodes = context.Get()->UninstallerSuccessCodes; - if (uninstallResult != 0 && (std::find(additionalSuccessCodes.begin(), additionalSuccessCodes.end(), uninstallResult) == additionalSuccessCodes.end())) + if (uninstallResult != 0) { const auto installedPackageVersion = context.Get(); Logging::Telemetry().LogUninstallerFailure( From 5c595663aff95da42b7e554e312775621bdcfba6 Mon Sep 17 00:00:00 2001 From: David Bennett Date: Mon, 22 Sep 2025 13:05:11 -0700 Subject: [PATCH 5/6] Update release notes --- doc/ReleaseNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ReleaseNotes.md b/doc/ReleaseNotes.md index fcf8c6e1d3..72afc0f4d3 100644 --- a/doc/ReleaseNotes.md +++ b/doc/ReleaseNotes.md @@ -2,6 +2,7 @@ * MCP server available; run `winget mcp` for assistance on configuring your client. * App Installer now uses WinUI 3. The package dependency on WinUI 2 has been replaced by a dependency on the Windows App Runtime 1.7. * Manifest schema and validation updated to v1.12. This version update adds "Font" as an InstallerType and NestedInstallerType. +* Added UninstallerSwitches and UninstallerSuccessCodes to the manifest schema for v1.12. ## Bug Fixes * Manifest validation no longer fails using `UTF-8 BOM` encoding when the schema header is on the first line From b69b32203640a01a9c0d465d1a4d0e97357db564 Mon Sep 17 00:00:00 2001 From: David Bennett Date: Thu, 25 Sep 2025 09:58:46 -0700 Subject: [PATCH 6/6] Fix schema formatting --- .../latest/manifest.installer.latest.json | 1520 +++++++-------- .../latest/manifest.singleton.latest.json | 1702 ++++++++--------- 2 files changed, 1611 insertions(+), 1611 deletions(-) diff --git a/schemas/JSON/manifests/latest/manifest.installer.latest.json b/schemas/JSON/manifests/latest/manifest.installer.latest.json index cfc7a7a7d8..d615f2d84e 100644 --- a/schemas/JSON/manifests/latest/manifest.installer.latest.json +++ b/schemas/JSON/manifests/latest/manifest.installer.latest.json @@ -2,838 +2,838 @@ "$id": "https://aka.ms/winget-manifest.installer.1.12.0.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "A representation of a single-file manifest representing an app installers in the OWC. v1.12.0", - "definitions": { - "PackageIdentifier": { + "definitions": { + "PackageIdentifier": { + "type": "string", + "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", + "maxLength": 128, + "description": "The package unique identifier" + }, + "PackageVersion": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 128, + "description": "The package version" + }, + "Locale": { + "type": [ "string", "null" ], + "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", + "maxLength": 20, + "description": "The installer meta-data locale" + }, + "Channel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 16, + "description": "The distribution channel" + }, + "Platform": { + "type": [ "array", "null" ], + "items": { + "title": "Platform", + "type": "string", + "enum": [ + "Windows.Desktop", + "Windows.Universal" + ] + }, + "maxItems": 2, + "uniqueItems": true, + "description": "The installer supported operating system" + }, + "MinimumOSVersion": { + "type": [ "string", "null" ], + "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", + "description": "The installer minimum operating system version" + }, + "Url": { + "type": [ "string", "null" ], + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "Url type" + }, + "InstallerType": { + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "zip", + "inno", + "nullsoft", + "wix", + "burn", + "pwa", + "portable", + "font" + ], + "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" + }, + "NestedInstallerType": { + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "inno", + "nullsoft", + "wix", + "burn", + "portable", + "font" + ], + "description": "Enumeration of supported nested installer types contained inside an archive file" + }, + "NestedInstallerFiles": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "NestedInstallerFile", + "properties": { + "RelativeFilePath": { "type": "string", - "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", - "maxLength": 128, - "description": "The package unique identifier" + "minLength": 1, + "maxLength": 512, + "description": "The relative path to the nested installer file" + }, + "PortableCommandAlias": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 40, + "description": "The command alias to be used for calling the package. Only applies to the nested portable package" + } }, - "PackageVersion": { + "required": [ "RelativeFilePath" ], + "description": "A nested installer file contained inside an archive" + }, + "maxItems": 1024, + "description": "List of nested installer files contained inside an archive" + }, + "Architecture": { + "type": "string", + "enum": [ + "x86", + "x64", + "arm", + "arm64", + "neutral" + ], + "description": "The installer target architecture" + }, + "Scope": { + "type": [ "string", "null" ], + "enum": [ + "user", + "machine" + ], + "description": "Scope indicates if the installer is per user or per machine" + }, + "InstallModes": { + "type": [ "array", "null" ], + "items": { + "title": "InstallModes", + "type": "string", + "enum": [ + "interactive", + "silent", + "silentWithProgress" + ] + }, + "maxItems": 3, + "uniqueItems": true, + "description": "List of supported installer modes" + }, + "InstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" + }, + "InstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Upgrade": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the installer by winget" + }, + "Repair": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair." + } + } + }, + "InstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the installer after execution" + }, + "InstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero installer success exit codes other than known default values by winget" + }, + "UninstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the uninstaller by winget" + } + } + }, + "UninstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the uninstaller after execution" + }, + "UninstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + }, + "ExpectedReturnCodes": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "ExpectedReturnCode", + "properties": { + "InstallerReturnCode": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "ReturnResponse": { "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 128, - "description": "The package version" - }, - "Locale": { - "type": [ "string", "null" ], - "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", - "maxLength": 20, - "description": "The installer meta-data locale" + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] + }, + "ReturnResponseUrl": { + "$ref": "#/definitions/Url", + "description": "The return response url to provide additional guidance for expected return codes" + } }, - "Channel": { - "type": [ "string", "null" ], + "required": [ "InstallerReturnCode", "ReturnResponse" ] + }, + "maxItems": 128, + "description": "Installer exit codes for common errors" + }, + "UpgradeBehavior": { + "type": [ "string", "null" ], + "enum": [ + "install", + "uninstallPrevious", + "deny" + ], + "description": "The upgrade method" + }, + "Commands": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of commands or aliases to run the package" + }, + "Protocols": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "maxLength": 2048 + }, + "maxItems": 64, + "uniqueItems": true, + "description": "List of protocols the package provides a handler for" + }, + "FileExtensions": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 64 + }, + "maxItems": 512, + "uniqueItems": true, + "description": "List of file extensions the package could support" + }, + "Dependencies": { + "type": [ "object", "null" ], + "properties": { + "WindowsFeatures": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows feature dependencies" + }, + "WindowsLibraries": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows library dependencies" + }, + "PackageDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "properties": { + "PackageIdentifier": { + "$ref": "#/definitions/PackageIdentifier" + }, + "MinimumVersion": { + "$ref": "#/definitions/PackageVersion" + } + }, + "required": [ "PackageIdentifier" ] + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of package dependencies from current source" + }, + "ExternalDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "string", "minLength": 1, - "maxLength": 16, - "description": "The distribution channel" + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of external package dependencies" + } + } + }, + "PackageFamilyName": { + "type": [ "string", "null" ], + "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", + "maxLength": 255, + "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" + }, + "ProductCode": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 255, + "description": "ProductCode could be used for correlation of packages across sources" + }, + "Capabilities": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer capabilities" + }, + "RestrictedCapabilities": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer restricted capabilities" + }, + "Market": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "description": "The installer target market" + }, + "MarketArray": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 256, + "items": { + "$ref": "#/definitions/Market" + }, + "description": "Array of markets" + }, + "Markets": { + "description": "The installer markets", + "type": [ "object", "null" ], + "oneOf": [ + { + "properties": { + "AllowedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "AllowedMarkets" ] }, - "Platform": { - "type": [ "array", "null" ], - "items": { - "title": "Platform", + { + "properties": { + "ExcludedMarkets": { + "$ref": "#/definitions/MarketArray" + } + }, + "required": [ "ExcludedMarkets" ] + } + ] + }, + "InstallerAbortsTerminal": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer will abort terminal. Default is false" + }, + "ReleaseDate": { + "type": [ "string", "null" ], + "format": "date", + "description": "The installer release date" + }, + "InstallLocationRequired": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer requires an install location provided" + }, + "RequireExplicitUpgrade": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer should be pinned by default from upgrade" + }, + "DisplayInstallWarnings": { + "type": [ "boolean", "null" ], + "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." + }, + "UnsupportedOSArchitectures": { + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedOSArchitecture", + "enum": [ + "x86", + "x64", + "arm", + "arm64" + ] + }, + "description": "List of OS architectures the installer does not support" + }, + "UnsupportedArguments": { + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedArgument", + "enum": [ + "log", + "location" + ] + }, + "description": "List of winget arguments the installer does not support" + }, + "AppsAndFeaturesEntry": { + "type": "object", + "properties": { + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The DisplayName registry value" + }, + "Publisher": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The Publisher registry value" + }, + "DisplayVersion": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 128, + "description": "The DisplayVersion registry value" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "UpgradeCode": { + "$ref": "#/definitions/ProductCode" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + } + }, + "description": "Various key values under installer's ARP entry" + }, + "AppsAndFeaturesEntries": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 128, + "items": { + "$ref": "#/definitions/AppsAndFeaturesEntry" + }, + "description": "List of ARP entries." + }, + "ElevationRequirement": { + "type": [ "string", "null" ], + "enum": [ + "elevationRequired", + "elevationProhibited", + "elevatesSelf" + ], + "description": "The installer's elevation requirement" + }, + "InstallationMetadata": { + "type": "object", + "title": "InstallationMetadata", + "properties": { + "DefaultInstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Represents the default installed package location. Used for deeper installation detection." + }, + "Files": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 2048, + "items": { + "type": "object", + "title": "InstalledFile", + "properties": { + "RelativeFilePath": { "type": "string", + "minLength": 1, + "maxLength": 2048, + "description": "The relative path to the installed file." + }, + "FileSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the installed file." + }, + "FileType": { + "type": [ "string", "null" ], "enum": [ - "Windows.Desktop", - "Windows.Universal" - ] + "launch", + "uninstall", + "other" + ], + "description": "The optional installed file type. If not specified, the file is treated as other." + }, + "InvocationParameter": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Optional parameter for invocable files." + }, + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "Optional display name for invocable files." + } + }, + "required": [ "RelativeFilePath" ], + "description": "Represents an installed file." + }, + "description": "List of installed files." + } + }, + "description": "Details about the installation. Used for deeper installation detection." + }, + "DownloadCommandProhibited": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." + }, + "RepairBehavior": { + "type": [ "string", "null" ], + "enum": [ + "modify", + "uninstaller", + "installer" + ], + "description": "The repair method" + }, + "ArchiveBinariesDependOnPath": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." + }, + "Authentication": { + "type": [ "object", "null" ], + "properties": { + "AuthenticationType": { + "type": "string", + "enum": [ + "none", + "microsoftEntraId", + "microsoftEntraIdForAzureBlobStorage" + ], + "description": "The authentication type" + }, + "MicrosoftEntraIdAuthenticationInfo": { + "type": [ "object", "null" ], + "properties": { + "Resource": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The resource value for Microsoft Entra Id authentication." }, - "maxItems": 2, - "uniqueItems": true, - "description": "The installer supported operating system" + "Scope": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The scope value for Microsoft Entra Id authentication." + } + }, + "description": "The Microsoft Entra Id authentication info" + } + }, + "required": [ + "AuthenticationType" + ], + "description": "The authentication requirement for downloading the installer." + }, + "Installer": { + "type": "object", + "properties": { + "InstallerLocale": { + "$ref": "#/definitions/Locale" + }, + "Platform": { + "$ref": "#/definitions/Platform" }, "MinimumOSVersion": { - "type": [ "string", "null" ], - "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", - "description": "The installer minimum operating system version" + "$ref": "#/definitions/MinimumOSVersion" }, - "Url": { - "type": [ "string", "null" ], - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "Url type" + "Architecture": { + "$ref": "#/definitions/Architecture" }, "InstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "zip", - "inno", - "nullsoft", - "wix", - "burn", - "pwa", - "portable", - "font" - ], - "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" + "$ref": "#/definitions/InstallerType" }, "NestedInstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "inno", - "nullsoft", - "wix", - "burn", - "portable", - "font" - ], - "description": "Enumeration of supported nested installer types contained inside an archive file" + "$ref": "#/definitions/NestedInstallerType" }, "NestedInstallerFiles": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "NestedInstallerFile", - "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "description": "The relative path to the nested installer file" - }, - "PortableCommandAlias": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 40, - "description": "The command alias to be used for calling the package. Only applies to the nested portable package" - } - }, - "required": [ "RelativeFilePath" ], - "description": "A nested installer file contained inside an archive" - }, - "maxItems": 1024, - "description": "List of nested installer files contained inside an archive" - }, - "Architecture": { - "type": "string", - "enum": [ - "x86", - "x64", - "arm", - "arm64", - "neutral" - ], - "description": "The installer target architecture" + "$ref": "#/definitions/NestedInstallerFiles" }, "Scope": { - "type": [ "string", "null" ], - "enum": [ - "user", - "machine" - ], - "description": "Scope indicates if the installer is per user or per machine" + "$ref": "#/definitions/Scope" }, - "InstallModes": { - "type": [ "array", "null" ], - "items": { - "title": "InstallModes", - "type": "string", - "enum": [ - "interactive", - "silent", - "silentWithProgress" - ] - }, - "maxItems": 3, - "uniqueItems": true, - "description": "List of supported installer modes" + "InstallerUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The installer Url" }, - "InstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" - }, - "InstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Upgrade": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the installer by winget" - }, - "Repair": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair." - } - } + "InstallerSha256": { + "type": "string", + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Sha256 is required. Sha256 of the installer" }, - "InstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the installer after execution" - }, - "InstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero installer success exit codes other than known default values by winget" + "SignatureSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" }, - "UninstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the uninstaller by winget" - } - } + "InstallModes": { + "$ref": "#/definitions/InstallModes" }, - "UninstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the uninstaller after execution" + "InstallerSwitches": { + "$ref": "#/definitions/InstallerSwitches" }, - "UninstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/UninstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + "InstallerSuccessCodes": { + "$ref": "#/definitions/InstallerSuccessCodes" }, "ExpectedReturnCodes": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "ExpectedReturnCode", - "properties": { - "InstallerReturnCode": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "ReturnResponse": { - "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, - "ReturnResponseUrl": { - "$ref": "#/definitions/Url", - "description": "The return response url to provide additional guidance for expected return codes" - } - }, - "required": [ "InstallerReturnCode", "ReturnResponse" ] - }, - "maxItems": 128, - "description": "Installer exit codes for common errors" + "$ref": "#/definitions/ExpectedReturnCodes" }, "UpgradeBehavior": { - "type": [ "string", "null" ], - "enum": [ - "install", - "uninstallPrevious", - "deny" - ], - "description": "The upgrade method" + "$ref": "#/definitions/UpgradeBehavior" }, "Commands": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of commands or aliases to run the package" + "$ref": "#/definitions/Commands" }, "Protocols": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "maxLength": 2048 - }, - "maxItems": 64, - "uniqueItems": true, - "description": "List of protocols the package provides a handler for" + "$ref": "#/definitions/Protocols" }, "FileExtensions": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 64 - }, - "maxItems": 512, - "uniqueItems": true, - "description": "List of file extensions the package could support" + "$ref": "#/definitions/FileExtensions" }, "Dependencies": { - "type": [ "object", "null" ], - "properties": { - "WindowsFeatures": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows feature dependencies" - }, - "WindowsLibraries": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows library dependencies" - }, - "PackageDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "properties": { - "PackageIdentifier": { - "$ref": "#/definitions/PackageIdentifier" - }, - "MinimumVersion": { - "$ref": "#/definitions/PackageVersion" - } - }, - "required": [ "PackageIdentifier" ] - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of package dependencies from current source" - }, - "ExternalDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of external package dependencies" - } - } + "$ref": "#/definitions/Dependencies" }, "PackageFamilyName": { - "type": [ "string", "null" ], - "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", - "maxLength": 255, - "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" + "$ref": "#/definitions/PackageFamilyName" }, "ProductCode": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 255, - "description": "ProductCode could be used for correlation of packages across sources" + "$ref": "#/definitions/ProductCode" }, "Capabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer capabilities" + "$ref": "#/definitions/Capabilities" }, "RestrictedCapabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer restricted capabilities" - }, - "Market": { - "type": "string", - "pattern": "^[A-Z]{2}$", - "description": "The installer target market" - }, - "MarketArray": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 256, - "items": { - "$ref": "#/definitions/Market" - }, - "description": "Array of markets" + "$ref": "#/definitions/RestrictedCapabilities" }, "Markets": { - "description": "The installer markets", - "type": [ "object", "null" ], - "oneOf": [ - { - "properties": { - "AllowedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "AllowedMarkets" ] - }, - { - "properties": { - "ExcludedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "ExcludedMarkets" ] - } - ] + "$ref": "#/definitions/Markets" }, "InstallerAbortsTerminal": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer will abort terminal. Default is false" + "$ref": "#/definitions/InstallerAbortsTerminal" }, "ReleaseDate": { - "type": [ "string", "null" ], - "format": "date", - "description": "The installer release date" + "$ref": "#/definitions/ReleaseDate" }, "InstallLocationRequired": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer requires an install location provided" + "$ref": "#/definitions/InstallLocationRequired" }, "RequireExplicitUpgrade": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer should be pinned by default from upgrade" + "$ref": "#/definitions/RequireExplicitUpgrade" }, "DisplayInstallWarnings": { - "type": [ "boolean", "null" ], - "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." + "$ref": "#/definitions/DisplayInstallWarnings" }, "UnsupportedOSArchitectures": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedOSArchitecture", - "enum": [ - "x86", - "x64", - "arm", - "arm64" - ] - }, - "description": "List of OS architectures the installer does not support" + "$ref": "#/definitions/UnsupportedOSArchitectures" }, "UnsupportedArguments": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedArgument", - "enum": [ - "log", - "location" - ] - }, - "description": "List of winget arguments the installer does not support" - }, - "AppsAndFeaturesEntry": { - "type": "object", - "properties": { - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The DisplayName registry value" - }, - "Publisher": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The Publisher registry value" - }, - "DisplayVersion": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 128, - "description": "The DisplayVersion registry value" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" - }, - "UpgradeCode": { - "$ref": "#/definitions/ProductCode" - }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - } - }, - "description": "Various key values under installer's ARP entry" + "$ref": "#/definitions/UnsupportedArguments" }, "AppsAndFeaturesEntries": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 128, - "items": { - "$ref": "#/definitions/AppsAndFeaturesEntry" - }, - "description": "List of ARP entries." + "$ref": "#/definitions/AppsAndFeaturesEntries" }, "ElevationRequirement": { - "type": [ "string", "null" ], - "enum": [ - "elevationRequired", - "elevationProhibited", - "elevatesSelf" - ], - "description": "The installer's elevation requirement" + "$ref": "#/definitions/ElevationRequirement" }, "InstallationMetadata": { - "type": "object", - "title": "InstallationMetadata", - "properties": { - "DefaultInstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Represents the default installed package location. Used for deeper installation detection." - }, - "Files": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 2048, - "items": { - "type": "object", - "title": "InstalledFile", - "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 2048, - "description": "The relative path to the installed file." - }, - "FileSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the installed file." - }, - "FileType": { - "type": [ "string", "null" ], - "enum": [ - "launch", - "uninstall", - "other" - ], - "description": "The optional installed file type. If not specified, the file is treated as other." - }, - "InvocationParameter": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Optional parameter for invocable files." - }, - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "Optional display name for invocable files." - } - }, - "required": [ "RelativeFilePath" ], - "description": "Represents an installed file." - }, - "description": "List of installed files." - } - }, - "description": "Details about the installation. Used for deeper installation detection." + "$ref": "#/definitions/InstallationMetadata" }, "DownloadCommandProhibited": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." + "$ref": "#/definitions/DownloadCommandProhibited" }, "RepairBehavior": { - "type": [ "string", "null" ], - "enum": [ - "modify", - "uninstaller", - "installer" - ], - "description": "The repair method" + "$ref": "#/definitions/RepairBehavior" }, "ArchiveBinariesDependOnPath": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." + "$ref": "#/definitions/ArchiveBinariesDependOnPath" }, "Authentication": { - "type": [ "object", "null" ], - "properties": { - "AuthenticationType": { - "type": "string", - "enum": [ - "none", - "microsoftEntraId", - "microsoftEntraIdForAzureBlobStorage" - ], - "description": "The authentication type" - }, - "MicrosoftEntraIdAuthenticationInfo": { - "type": [ "object", "null" ], - "properties": { - "Resource": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The resource value for Microsoft Entra Id authentication." - }, - "Scope": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The scope value for Microsoft Entra Id authentication." - } - }, - "description": "The Microsoft Entra Id authentication info" - } - }, - "required": [ - "AuthenticationType" - ], - "description": "The authentication requirement for downloading the installer." + "$ref": "#/definitions/Authentication" }, - "Installer": { - "type": "object", - "properties": { - "InstallerLocale": { - "$ref": "#/definitions/Locale" - }, - "Platform": { - "$ref": "#/definitions/Platform" - }, - "MinimumOSVersion": { - "$ref": "#/definitions/MinimumOSVersion" - }, - "Architecture": { - "$ref": "#/definitions/Architecture" - }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - }, - "NestedInstallerType": { - "$ref": "#/definitions/NestedInstallerType" - }, - "NestedInstallerFiles": { - "$ref": "#/definitions/NestedInstallerFiles" - }, - "Scope": { - "$ref": "#/definitions/Scope" - }, - "InstallerUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The installer Url" - }, - "InstallerSha256": { - "type": "string", - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Sha256 is required. Sha256 of the installer" - }, - "SignatureSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" - }, - "InstallModes": { - "$ref": "#/definitions/InstallModes" - }, - "InstallerSwitches": { - "$ref": "#/definitions/InstallerSwitches" - }, - "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" - }, - "UninstallerSwitches": { - "$ref": "#/definitions/UninstallerSwitches" - }, - "UninstallerSuccessCodes": { - "$ref": "#/definitions/UninstallerSuccessCodes" - }, - "ExpectedReturnCodes": { - "$ref": "#/definitions/ExpectedReturnCodes" - }, - "UpgradeBehavior": { - "$ref": "#/definitions/UpgradeBehavior" - }, - "Commands": { - "$ref": "#/definitions/Commands" - }, - "Protocols": { - "$ref": "#/definitions/Protocols" - }, - "FileExtensions": { - "$ref": "#/definitions/FileExtensions" - }, - "Dependencies": { - "$ref": "#/definitions/Dependencies" - }, - "PackageFamilyName": { - "$ref": "#/definitions/PackageFamilyName" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" - }, - "Capabilities": { - "$ref": "#/definitions/Capabilities" - }, - "RestrictedCapabilities": { - "$ref": "#/definitions/RestrictedCapabilities" - }, - "Markets": { - "$ref": "#/definitions/Markets" - }, - "InstallerAbortsTerminal": { - "$ref": "#/definitions/InstallerAbortsTerminal" - }, - "ReleaseDate": { - "$ref": "#/definitions/ReleaseDate" - }, - "InstallLocationRequired": { - "$ref": "#/definitions/InstallLocationRequired" - }, - "RequireExplicitUpgrade": { - "$ref": "#/definitions/RequireExplicitUpgrade" - }, - "DisplayInstallWarnings": { - "$ref": "#/definitions/DisplayInstallWarnings" - }, - "UnsupportedOSArchitectures": { - "$ref": "#/definitions/UnsupportedOSArchitectures" - }, - "UnsupportedArguments": { - "$ref": "#/definitions/UnsupportedArguments" - }, - "AppsAndFeaturesEntries": { - "$ref": "#/definitions/AppsAndFeaturesEntries" - }, - "ElevationRequirement": { - "$ref": "#/definitions/ElevationRequirement" - }, - "InstallationMetadata": { - "$ref": "#/definitions/InstallationMetadata" - }, - "DownloadCommandProhibited": { - "$ref": "#/definitions/DownloadCommandProhibited" - }, - "RepairBehavior": { - "$ref": "#/definitions/RepairBehavior" - }, - "ArchiveBinariesDependOnPath": { - "$ref": "#/definitions/ArchiveBinariesDependOnPath" - }, - "Authentication": { - "$ref": "#/definitions/Authentication" - } - }, - "required": [ - "Architecture", - "InstallerUrl", - "InstallerSha256" - ] + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" } - }, + }, + "required": [ + "Architecture", + "InstallerUrl", + "InstallerSha256" + ] + } + }, "type": "object", "properties": { "PackageIdentifier": { @@ -875,12 +875,6 @@ "InstallerSuccessCodes": { "$ref": "#/definitions/InstallerSuccessCodes" }, - "UninstallerSwitches": { - "$ref": "#/definitions/UninstallerSwitches" - }, - "UninstallerSuccessCodes": { - "$ref": "#/definitions/UninstallerSuccessCodes" - }, "ExpectedReturnCodes": { "$ref": "#/definitions/ExpectedReturnCodes" }, @@ -956,6 +950,12 @@ "Authentication": { "$ref": "#/definitions/Authentication" }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" + }, "Installers": { "type": "array", "items": { diff --git a/schemas/JSON/manifests/latest/manifest.singleton.latest.json b/schemas/JSON/manifests/latest/manifest.singleton.latest.json index b2c1fada56..edea765ed9 100644 --- a/schemas/JSON/manifests/latest/manifest.singleton.latest.json +++ b/schemas/JSON/manifests/latest/manifest.singleton.latest.json @@ -2,939 +2,939 @@ "$id": "https://aka.ms/winget-manifest.singleton.1.12.0.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "A representation of a single-file manifest representing an app in the OWC. v1.12.0", - "definitions": { - "PackageIdentifier": { - "type": "string", - "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", - "maxLength": 128, - "description": "The package unique identifier" + "definitions": { + "PackageIdentifier": { + "type": "string", + "pattern": "^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$", + "maxLength": 128, + "description": "The package unique identifier" + }, + "PackageVersion": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 128, + "description": "The package version" + }, + "Locale": { + "type": [ "string", "null" ], + "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", + "maxLength": 20, + "description": "The package meta-data locale" + }, + "Url": { + "type": [ "string", "null" ], + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "Optional Url type" + }, + "Tag": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 40, + "description": "Package moniker or tag" + }, + "Agreement": { + "type": "object", + "properties": { + "AgreementLabel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 100, + "description": "The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel" }, - "PackageVersion": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 128, - "description": "The package version" + "Agreement": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 10000, + "description": "The agreement text content." }, - "Locale": { - "type": [ "string", "null" ], - "pattern": "^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$", - "maxLength": 20, - "description": "The package meta-data locale" + "AgreementUrl": { + "$ref": "#/definitions/Url", + "description": "The agreement URL." + } + } + }, + "Documentation": { + "type": "object", + "properties": { + "DocumentLabel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 100, + "description": "The label of the documentation for providing software guides such as manuals and troubleshooting URLs." }, - "Url": { - "type": [ "string", "null" ], - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "Optional Url type" + "DocumentUrl": { + "$ref": "#/definitions/Url", + "description": "The documentation URL." + } + } + }, + "Icon": { + "type": "object", + "properties": { + "IconUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The url of the hosted icon file" + }, + "IconFileType": { + "type": "string", + "enum": [ + "png", + "jpeg", + "ico" + ], + "description": "The icon file type" + }, + "IconResolution": { + "type": [ "string", "null" ], + "enum": [ + "custom", + "16x16", + "20x20", + "24x24", + "30x30", + "32x32", + "36x36", + "40x40", + "48x48", + "60x60", + "64x64", + "72x72", + "80x80", + "96x96", + "256x256" + ], + "description": "Optional icon resolution" + }, + "IconTheme": { + "type": [ "string", "null" ], + "enum": [ + "default", + "light", + "dark", + "highContrast" + ], + "description": "Optional icon theme" }, - "Tag": { + "IconSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the icon file" + } + }, + "required": [ + "IconUrl", + "IconFileType" + ] + }, + "Channel": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 16, + "description": "The distribution channel" + }, + "Platform": { + "type": [ "array", "null" ], + "items": { + "title": "Platform", + "type": "string", + "enum": [ + "Windows.Desktop", + "Windows.Universal" + ] + }, + "maxItems": 2, + "uniqueItems": true, + "description": "The installer supported operating system" + }, + "MinimumOSVersion": { + "type": [ "string", "null" ], + "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", + "description": "The installer minimum operating system version" + }, + "InstallerType": { + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "zip", + "inno", + "nullsoft", + "wix", + "burn", + "pwa", + "portable", + "font" + ], + "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" + }, + "NestedInstallerType": { + "type": [ "string", "null" ], + "enum": [ + "msix", + "msi", + "appx", + "exe", + "inno", + "nullsoft", + "wix", + "burn", + "portable", + "font" + ], + "description": "Enumeration of supported nested installer types contained inside an archive file" + }, + "NestedInstallerFiles": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "NestedInstallerFile", + "properties": { + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "description": "The relative path to the nested installer file" + }, + "PortableCommandAlias": { "type": [ "string", "null" ], "minLength": 1, "maxLength": 40, - "description": "Package moniker or tag" + "description": "The command alias to be used for calling the package. Only applies to the nested portable package" + } }, - "Agreement": { + "required": [ "RelativeFilePath" ], + "description": "A nested installer file contained inside an archive" + }, + "maxItems": 1024, + "description": "List of nested installer files contained inside an archive" + }, + "Architecture": { + "type": "string", + "enum": [ + "x86", + "x64", + "arm", + "arm64", + "neutral" + ], + "description": "The installer target architecture" + }, + "Scope": { + "type": [ "string", "null" ], + "enum": [ + "user", + "machine" + ], + "description": "Scope indicates if the installer is per user or per machine" + }, + "InstallModes": { + "type": [ "array", "null" ], + "items": { + "title": "InstallModes", + "type": "string", + "enum": [ + "interactive", + "silent", + "silentWithProgress" + ] + }, + "maxItems": 3, + "uniqueItems": true, + "description": "List of supported installer modes" + }, + "InstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" + }, + "InstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Upgrade": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the installer by winget" + }, + "Repair": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair" + } + } + }, + "InstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the installer after execution" + }, + "InstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero installer success exit codes other than known default values by winget" + }, + "UninstallerSwitches": { + "type": "object", + "properties": { + "Silent": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" + }, + "SilentWithProgress": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" + }, + "Interactive": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" + }, + "Log": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" + }, + "Custom": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Custom switches will be passed directly to the uninstaller by winget" + } + } + }, + "UninstallerReturnCode": { + "type": "integer", + "format": "long", + "not": { + "enum": [ 0 ] + }, + "minimum": -2147483648, + "maximum": 4294967295, + "description": "An exit code that can be returned by the uninstaller after execution" + }, + "UninstallerSuccessCodes": { + "type": [ "array", "null" ], + "items": { + "$ref": "#/definitions/UninstallerReturnCode" + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + }, + "ExpectedReturnCodes": { + "type": [ "array", "null" ], + "items": { + "type": "object", + "title": "ExpectedReturnCode", + "properties": { + "InstallerReturnCode": { + "$ref": "#/definitions/InstallerReturnCode" + }, + "ReturnResponse": { + "type": "string", + "enum": [ + "packageInUse", + "packageInUseByApplication", + "installInProgress", + "fileInUse", + "missingDependency", + "diskFull", + "insufficientMemory", + "invalidParameter", + "noNetwork", + "contactSupport", + "rebootRequiredToFinish", + "rebootRequiredForInstall", + "rebootInitiated", + "cancelledByUser", + "alreadyInstalled", + "downgrade", + "blockedByPolicy", + "systemNotSupported", + "custom" + ] + }, + "ReturnResponseUrl": { + "$ref": "#/definitions/Url", + "description": "The return response url to provide additional guidance for expected return codes" + } + }, + "required": [ "InstallerReturnCode", "ReturnResponse" ] + }, + "maxItems": 128, + "description": "Installer exit codes for common errors" + }, + "UpgradeBehavior": { + "type": [ "string", "null" ], + "enum": [ + "install", + "uninstallPrevious", + "deny" + ], + "description": "The upgrade method" + }, + "Commands": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of commands or aliases to run the package" + }, + "Protocols": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "maxLength": 2048 + }, + "maxItems": 64, + "uniqueItems": true, + "description": "List of protocols the package provides a handler for" + }, + "FileExtensions": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", + "maxLength": 64 + }, + "maxItems": 512, + "uniqueItems": true, + "description": "List of file extensions the package could support" + }, + "Dependencies": { + "type": [ "object", "null" ], + "properties": { + "WindowsFeatures": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows feature dependencies" + }, + "WindowsLibraries": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of Windows library dependencies" + }, + "PackageDependencies": { + "type": [ "array", "null" ], + "items": { "type": "object", "properties": { - "AgreementLabel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 100, - "description": "The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel" - }, - "Agreement": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 10000, - "description": "The agreement text content." - }, - "AgreementUrl": { - "$ref": "#/definitions/Url", - "description": "The agreement URL." - } + "PackageIdentifier": { + "$ref": "#/definitions/PackageIdentifier" + }, + "MinimumVersion": { + "$ref": "#/definitions/PackageVersion" + } + }, + "required": [ "PackageIdentifier" ] + }, + "maxItems": 16, + "description": "List of package dependencies from current source" + }, + "ExternalDependencies": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "maxItems": 16, + "uniqueItems": true, + "description": "List of external package dependencies" + } + } + }, + "PackageFamilyName": { + "type": [ "string", "null" ], + "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", + "maxLength": 255, + "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" + }, + "ProductCode": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 255, + "description": "ProductCode could be used for correlation of packages across sources" + }, + "Capabilities": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer capabilities" + }, + "RestrictedCapabilities": { + "type": [ "array", "null" ], + "items": { + "type": "string", + "minLength": 1, + "maxLength": 40 + }, + "maxItems": 1000, + "uniqueItems": true, + "description": "List of appx or msix installer restricted capabilities" + }, + "Market": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "description": "The installer target market" + }, + "MarketArray": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 256, + "items": { + "$ref": "#/definitions/Market" + }, + "description": "Array of markets" + }, + "Markets": { + "description": "The installer markets", + "type": [ "object", "null" ], + "oneOf": [ + { + "properties": { + "AllowedMarkets": { + "$ref": "#/definitions/MarketArray" } + }, + "required": [ "AllowedMarkets" ] }, - "Documentation": { - "type": "object", - "properties": { - "DocumentLabel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 100, - "description": "The label of the documentation for providing software guides such as manuals and troubleshooting URLs." - }, - "DocumentUrl": { - "$ref": "#/definitions/Url", - "description": "The documentation URL." - } + { + "properties": { + "ExcludedMarkets": { + "$ref": "#/definitions/MarketArray" } + }, + "required": [ "ExcludedMarkets" ] + } + ] + }, + "InstallerAbortsTerminal": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer will abort terminal. Default is false" + }, + "ReleaseDate": { + "type": [ "string", "null" ], + "format": "date", + "description": "The installer release date" + }, + "InstallLocationRequired": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer requires an install location provided" + }, + "RequireExplicitUpgrade": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer should be pinned by default from upgrade" + }, + "DisplayInstallWarnings": { + "type": [ "boolean", "null" ], + "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." + }, + "UnsupportedOSArchitectures": { + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedOSArchitecture", + "enum": [ + "x86", + "x64", + "arm", + "arm64" + ] + }, + "description": "List of OS architectures the installer does not support" + }, + "UnsupportedArguments": { + "type": [ "array", "null" ], + "uniqueItems": true, + "items": { + "type": "string", + "title": "UnsupportedArgument", + "enum": [ + "log", + "location" + ] + }, + "description": "List of winget arguments the installer does not support" + }, + "AppsAndFeaturesEntry": { + "type": "object", + "properties": { + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The DisplayName registry value" }, - "Icon": { + "Publisher": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "The Publisher registry value" + }, + "DisplayVersion": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 128, + "description": "The DisplayVersion registry value" + }, + "ProductCode": { + "$ref": "#/definitions/ProductCode" + }, + "UpgradeCode": { + "$ref": "#/definitions/ProductCode" + }, + "InstallerType": { + "$ref": "#/definitions/InstallerType" + } + }, + "description": "Various key values under installer's ARP entry" + }, + "AppsAndFeaturesEntries": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 128, + "items": { + "$ref": "#/definitions/AppsAndFeaturesEntry" + }, + "description": "List of ARP entries." + }, + "ElevationRequirement": { + "type": [ "string", "null" ], + "enum": [ + "elevationRequired", + "elevationProhibited", + "elevatesSelf" + ], + "description": "The installer's elevation requirement" + }, + "InstallationMetadata": { + "type": "object", + "title": "InstallationMetadata", + "properties": { + "DefaultInstallLocation": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Represents the default installed package location. Used for deeper installation detection." + }, + "Files": { + "type": [ "array", "null" ], + "uniqueItems": true, + "maxItems": 2048, + "items": { "type": "object", + "title": "InstalledFile", "properties": { - "IconUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The url of the hosted icon file" - }, - "IconFileType": { - "type": "string", - "enum": [ - "png", - "jpeg", - "ico" - ], - "description": "The icon file type" - }, - "IconResolution": { - "type": [ "string", "null" ], - "enum": [ - "custom", - "16x16", - "20x20", - "24x24", - "30x30", - "32x32", - "36x36", - "40x40", - "48x48", - "60x60", - "64x64", - "72x72", - "80x80", - "96x96", - "256x256" - ], - "description": "Optional icon resolution" - }, - "IconTheme": { - "type": [ "string", "null" ], - "enum": [ - "default", - "light", - "dark", - "highContrast" - ], - "description": "Optional icon theme" - }, - "IconSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the icon file" - } + "RelativeFilePath": { + "type": "string", + "minLength": 1, + "maxLength": 2048, + "description": "The relative path to the installed file." + }, + "FileSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Optional Sha256 of the installed file." + }, + "FileType": { + "type": [ "string", "null" ], + "enum": [ + "launch", + "uninstall", + "other" + ], + "description": "The optional installed file type. If not specified, the file is treated as other." + }, + "InvocationParameter": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 2048, + "description": "Optional parameter for invocable files." + }, + "DisplayName": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 256, + "description": "Optional display name for invocable files." + } }, - "required": [ - "IconUrl", - "IconFileType" - ] + "required": [ "RelativeFilePath" ], + "description": "Represents an installed file." + }, + "description": "List of installed files." + } + }, + "description": "Details about the installation. Used for deeper installation detection." + }, + "DownloadCommandProhibited": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." + }, + "RepairBehavior": { + "type": [ "string", "null" ], + "enum": [ + "modify", + "uninstaller", + "installer" + ], + "description": "The repair method" + }, + "ArchiveBinariesDependOnPath": { + "type": [ "boolean", "null" ], + "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." + }, + "Authentication": { + "type": [ "object", "null" ], + "properties": { + "AuthenticationType": { + "type": "string", + "enum": [ + "none", + "microsoftEntraId", + "microsoftEntraIdForAzureBlobStorage" + ], + "description": "The authentication type" }, - "Channel": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 16, - "description": "The distribution channel" + "MicrosoftEntraIdAuthenticationInfo": { + "type": [ "object", "null" ], + "properties": { + "Resource": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The resource value for Microsoft Entra Id authentication." + }, + "Scope": { + "type": [ "string", "null" ], + "minLength": 1, + "maxLength": 512, + "description": "The scope value for Microsoft Entra Id authentication." + } + }, + "description": "The Microsoft Entra Id authentication info" + } + }, + "required": [ + "AuthenticationType" + ], + "description": "The authentication requirement for downloading the installer." + }, + "Installer": { + "type": "object", + "properties": { + "InstallerLocale": { + "$ref": "#/definitions/Locale" }, "Platform": { - "type": [ "array", "null" ], - "items": { - "title": "Platform", - "type": "string", - "enum": [ - "Windows.Desktop", - "Windows.Universal" - ] - }, - "maxItems": 2, - "uniqueItems": true, - "description": "The installer supported operating system" + "$ref": "#/definitions/Platform" }, "MinimumOSVersion": { - "type": [ "string", "null" ], - "pattern": "^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$", - "description": "The installer minimum operating system version" + "$ref": "#/definitions/MinimumOSVersion" + }, + "Architecture": { + "$ref": "#/definitions/Architecture" }, "InstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "zip", - "inno", - "nullsoft", - "wix", - "burn", - "pwa", - "portable", - "font" - ], - "description": "Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level" + "$ref": "#/definitions/InstallerType" }, "NestedInstallerType": { - "type": [ "string", "null" ], - "enum": [ - "msix", - "msi", - "appx", - "exe", - "inno", - "nullsoft", - "wix", - "burn", - "portable", - "font" - ], - "description": "Enumeration of supported nested installer types contained inside an archive file" + "$ref": "#/definitions/NestedInstallerType" }, "NestedInstallerFiles": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "NestedInstallerFile", - "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "description": "The relative path to the nested installer file" - }, - "PortableCommandAlias": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 40, - "description": "The command alias to be used for calling the package. Only applies to the nested portable package" - } - }, - "required": [ "RelativeFilePath" ], - "description": "A nested installer file contained inside an archive" - }, - "maxItems": 1024, - "description": "List of nested installer files contained inside an archive" - }, - "Architecture": { - "type": "string", - "enum": [ - "x86", - "x64", - "arm", - "arm64", - "neutral" - ], - "description": "The installer target architecture" + "$ref": "#/definitions/NestedInstallerFiles" }, "Scope": { - "type": [ "string", "null" ], - "enum": [ - "user", - "machine" - ], - "description": "Scope indicates if the installer is per user or per machine" + "$ref": "#/definitions/Scope" }, - "InstallModes": { - "type": [ "array", "null" ], - "items": { - "title": "InstallModes", - "type": "string", - "enum": [ - "interactive", - "silent", - "silentWithProgress" - ] - }, - "maxItems": 3, - "uniqueItems": true, - "description": "List of supported installer modes" + "InstallerUrl": { + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, + "description": "The installer Url" }, - "InstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the installer when user chooses a silent or quiet install" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the installer when user chooses an interactive install" - }, - "InstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "InstallLocation is the value passed to the installer for custom install location. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the installer for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Upgrade": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Upgrade is the value that should be passed to the installer when user chooses an upgrade" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the installer by winget" - }, - "Repair": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair" - } - } + "InstallerSha256": { + "type": "string", + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "Sha256 is required. Sha256 of the installer" }, - "InstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the installer after execution" + "SignatureSha256": { + "type": [ "string", "null" ], + "pattern": "^[A-Fa-f0-9]{64}$", + "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" }, - "InstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero installer success exit codes other than known default values by winget" - }, - "UninstallerSwitches": { - "type": "object", - "properties": { - "Silent": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Silent is the value that should be passed to the uninstaller when user chooses a silent or quiet uninstall" - }, - "SilentWithProgress": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "SilentWithProgress is the value that should be passed to the uninstaller when user chooses a non-interactive uninstall" - }, - "Interactive": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Interactive is the value that should be passed to the uninstaller when user chooses an interactive uninstall" - }, - "Log": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "Log is the value passed to the uninstaller for custom log file path. token can be included in the switch value so that winget will replace the token with user provided path" - }, - "Custom": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Custom switches will be passed directly to the uninstaller by winget" - } - } + "InstallModes": { + "$ref": "#/definitions/InstallModes" }, - "UninstallerReturnCode": { - "type": "integer", - "format": "long", - "not": { - "enum": [ 0 ] - }, - "minimum": -2147483648, - "maximum": 4294967295, - "description": "An exit code that can be returned by the uninstaller after execution" + "InstallerSwitches": { + "$ref": "#/definitions/InstallerSwitches" }, - "UninstallerSuccessCodes": { - "type": [ "array", "null" ], - "items": { - "$ref": "#/definitions/UninstallerReturnCode" - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of additional non-zero uninstaller success exit codes other than known default values by winget" + "InstallerSuccessCodes": { + "$ref": "#/definitions/InstallerSuccessCodes" }, "ExpectedReturnCodes": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "title": "ExpectedReturnCode", - "properties": { - "InstallerReturnCode": { - "$ref": "#/definitions/InstallerReturnCode" - }, - "ReturnResponse": { - "type": "string", - "enum": [ - "packageInUse", - "packageInUseByApplication", - "installInProgress", - "fileInUse", - "missingDependency", - "diskFull", - "insufficientMemory", - "invalidParameter", - "noNetwork", - "contactSupport", - "rebootRequiredToFinish", - "rebootRequiredForInstall", - "rebootInitiated", - "cancelledByUser", - "alreadyInstalled", - "downgrade", - "blockedByPolicy", - "systemNotSupported", - "custom" - ] - }, - "ReturnResponseUrl": { - "$ref": "#/definitions/Url", - "description": "The return response url to provide additional guidance for expected return codes" - } - }, - "required": [ "InstallerReturnCode", "ReturnResponse" ] - }, - "maxItems": 128, - "description": "Installer exit codes for common errors" + "$ref": "#/definitions/ExpectedReturnCodes" }, "UpgradeBehavior": { - "type": [ "string", "null" ], - "enum": [ - "install", - "uninstallPrevious", - "deny" - ], - "description": "The upgrade method" + "$ref": "#/definitions/UpgradeBehavior" }, "Commands": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of commands or aliases to run the package" + "$ref": "#/definitions/Commands" }, "Protocols": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "maxLength": 2048 - }, - "maxItems": 64, - "uniqueItems": true, - "description": "List of protocols the package provides a handler for" + "$ref": "#/definitions/Protocols" }, "FileExtensions": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "pattern": "^[^\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]+$", - "maxLength": 64 - }, - "maxItems": 512, - "uniqueItems": true, - "description": "List of file extensions the package could support" + "$ref": "#/definitions/FileExtensions" }, "Dependencies": { - "type": [ "object", "null" ], - "properties": { - "WindowsFeatures": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows feature dependencies" - }, - "WindowsLibraries": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of Windows library dependencies" - }, - "PackageDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "object", - "properties": { - "PackageIdentifier": { - "$ref": "#/definitions/PackageIdentifier" - }, - "MinimumVersion": { - "$ref": "#/definitions/PackageVersion" - } - }, - "required": [ "PackageIdentifier" ] - }, - "maxItems": 16, - "description": "List of package dependencies from current source" - }, - "ExternalDependencies": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "maxItems": 16, - "uniqueItems": true, - "description": "List of external package dependencies" - } - } + "$ref": "#/definitions/Dependencies" }, "PackageFamilyName": { - "type": [ "string", "null" ], - "pattern": "^[A-Za-z0-9][-\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$", - "maxLength": 255, - "description": "PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources" + "$ref": "#/definitions/PackageFamilyName" }, "ProductCode": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 255, - "description": "ProductCode could be used for correlation of packages across sources" + "$ref": "#/definitions/ProductCode" }, "Capabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer capabilities" + "$ref": "#/definitions/Capabilities" }, "RestrictedCapabilities": { - "type": [ "array", "null" ], - "items": { - "type": "string", - "minLength": 1, - "maxLength": 40 - }, - "maxItems": 1000, - "uniqueItems": true, - "description": "List of appx or msix installer restricted capabilities" - }, - "Market": { - "type": "string", - "pattern": "^[A-Z]{2}$", - "description": "The installer target market" - }, - "MarketArray": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 256, - "items": { - "$ref": "#/definitions/Market" - }, - "description": "Array of markets" + "$ref": "#/definitions/RestrictedCapabilities" }, "Markets": { - "description": "The installer markets", - "type": [ "object", "null" ], - "oneOf": [ - { - "properties": { - "AllowedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "AllowedMarkets" ] - }, - { - "properties": { - "ExcludedMarkets": { - "$ref": "#/definitions/MarketArray" - } - }, - "required": [ "ExcludedMarkets" ] - } - ] + "$ref": "#/definitions/Markets" }, "InstallerAbortsTerminal": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer will abort terminal. Default is false" + "$ref": "#/definitions/InstallerAbortsTerminal" }, "ReleaseDate": { - "type": [ "string", "null" ], - "format": "date", - "description": "The installer release date" + "$ref": "#/definitions/ReleaseDate" }, "InstallLocationRequired": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer requires an install location provided" + "$ref": "#/definitions/InstallLocationRequired" }, "RequireExplicitUpgrade": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer should be pinned by default from upgrade" + "$ref": "#/definitions/RequireExplicitUpgrade" }, "DisplayInstallWarnings": { - "type": [ "boolean", "null" ], - "description": "Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications." + "$ref": "#/definitions/DisplayInstallWarnings" }, "UnsupportedOSArchitectures": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedOSArchitecture", - "enum": [ - "x86", - "x64", - "arm", - "arm64" - ] - }, - "description": "List of OS architectures the installer does not support" + "$ref": "#/definitions/UnsupportedOSArchitectures" }, "UnsupportedArguments": { - "type": [ "array", "null" ], - "uniqueItems": true, - "items": { - "type": "string", - "title": "UnsupportedArgument", - "enum": [ - "log", - "location" - ] - }, - "description": "List of winget arguments the installer does not support" - }, - "AppsAndFeaturesEntry": { - "type": "object", - "properties": { - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The DisplayName registry value" - }, - "Publisher": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "The Publisher registry value" - }, - "DisplayVersion": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 128, - "description": "The DisplayVersion registry value" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" - }, - "UpgradeCode": { - "$ref": "#/definitions/ProductCode" - }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - } - }, - "description": "Various key values under installer's ARP entry" + "$ref": "#/definitions/UnsupportedArguments" }, "AppsAndFeaturesEntries": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 128, - "items": { - "$ref": "#/definitions/AppsAndFeaturesEntry" - }, - "description": "List of ARP entries." + "$ref": "#/definitions/AppsAndFeaturesEntries" }, "ElevationRequirement": { - "type": [ "string", "null" ], - "enum": [ - "elevationRequired", - "elevationProhibited", - "elevatesSelf" - ], - "description": "The installer's elevation requirement" + "$ref": "#/definitions/ElevationRequirement" }, "InstallationMetadata": { - "type": "object", - "title": "InstallationMetadata", - "properties": { - "DefaultInstallLocation": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Represents the default installed package location. Used for deeper installation detection." - }, - "Files": { - "type": [ "array", "null" ], - "uniqueItems": true, - "maxItems": 2048, - "items": { - "type": "object", - "title": "InstalledFile", - "properties": { - "RelativeFilePath": { - "type": "string", - "minLength": 1, - "maxLength": 2048, - "description": "The relative path to the installed file." - }, - "FileSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Optional Sha256 of the installed file." - }, - "FileType": { - "type": [ "string", "null" ], - "enum": [ - "launch", - "uninstall", - "other" - ], - "description": "The optional installed file type. If not specified, the file is treated as other." - }, - "InvocationParameter": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 2048, - "description": "Optional parameter for invocable files." - }, - "DisplayName": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 256, - "description": "Optional display name for invocable files." - } - }, - "required": [ "RelativeFilePath" ], - "description": "Represents an installed file." - }, - "description": "List of installed files." - } - }, - "description": "Details about the installation. Used for deeper installation detection." + "$ref": "#/definitions/InstallationMetadata" }, "DownloadCommandProhibited": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the installer is prohibited from being downloaded for offline installation." + "$ref": "#/definitions/DownloadCommandProhibited" }, "RepairBehavior": { - "type": [ "string", "null" ], - "enum": [ - "modify", - "uninstaller", - "installer" - ], - "description": "The repair method" + "$ref": "#/definitions/RepairBehavior" }, "ArchiveBinariesDependOnPath": { - "type": [ "boolean", "null" ], - "description": "Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages." + "$ref": "#/definitions/ArchiveBinariesDependOnPath" }, "Authentication": { - "type": [ "object", "null" ], - "properties": { - "AuthenticationType": { - "type": "string", - "enum": [ - "none", - "microsoftEntraId", - "microsoftEntraIdForAzureBlobStorage" - ], - "description": "The authentication type" - }, - "MicrosoftEntraIdAuthenticationInfo": { - "type": [ "object", "null" ], - "properties": { - "Resource": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The resource value for Microsoft Entra Id authentication." - }, - "Scope": { - "type": [ "string", "null" ], - "minLength": 1, - "maxLength": 512, - "description": "The scope value for Microsoft Entra Id authentication." - } - }, - "description": "The Microsoft Entra Id authentication info" - } - }, - "required": [ - "AuthenticationType" - ], - "description": "The authentication requirement for downloading the installer." + "$ref": "#/definitions/Authentication" }, - "Installer": { - "type": "object", - "properties": { - "InstallerLocale": { - "$ref": "#/definitions/Locale" - }, - "Platform": { - "$ref": "#/definitions/Platform" - }, - "MinimumOSVersion": { - "$ref": "#/definitions/MinimumOSVersion" - }, - "Architecture": { - "$ref": "#/definitions/Architecture" - }, - "InstallerType": { - "$ref": "#/definitions/InstallerType" - }, - "NestedInstallerType": { - "$ref": "#/definitions/NestedInstallerType" - }, - "NestedInstallerFiles": { - "$ref": "#/definitions/NestedInstallerFiles" - }, - "Scope": { - "$ref": "#/definitions/Scope" - }, - "InstallerUrl": { - "type": "string", - "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", - "maxLength": 2048, - "description": "The installer Url" - }, - "InstallerSha256": { - "type": "string", - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "Sha256 is required. Sha256 of the installer" - }, - "SignatureSha256": { - "type": [ "string", "null" ], - "pattern": "^[A-Fa-f0-9]{64}$", - "description": "SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable" - }, - "InstallModes": { - "$ref": "#/definitions/InstallModes" - }, - "InstallerSwitches": { - "$ref": "#/definitions/InstallerSwitches" - }, - "InstallerSuccessCodes": { - "$ref": "#/definitions/InstallerSuccessCodes" - }, - "ExpectedReturnCodes": { - "$ref": "#/definitions/ExpectedReturnCodes" - }, - "UpgradeBehavior": { - "$ref": "#/definitions/UpgradeBehavior" - }, - "Commands": { - "$ref": "#/definitions/Commands" - }, - "Protocols": { - "$ref": "#/definitions/Protocols" - }, - "FileExtensions": { - "$ref": "#/definitions/FileExtensions" - }, - "Dependencies": { - "$ref": "#/definitions/Dependencies" - }, - "PackageFamilyName": { - "$ref": "#/definitions/PackageFamilyName" - }, - "ProductCode": { - "$ref": "#/definitions/ProductCode" - }, - "Capabilities": { - "$ref": "#/definitions/Capabilities" - }, - "RestrictedCapabilities": { - "$ref": "#/definitions/RestrictedCapabilities" - }, - "Markets": { - "$ref": "#/definitions/Markets" - }, - "InstallerAbortsTerminal": { - "$ref": "#/definitions/InstallerAbortsTerminal" - }, - "ReleaseDate": { - "$ref": "#/definitions/ReleaseDate" - }, - "InstallLocationRequired": { - "$ref": "#/definitions/InstallLocationRequired" - }, - "RequireExplicitUpgrade": { - "$ref": "#/definitions/RequireExplicitUpgrade" - }, - "DisplayInstallWarnings": { - "$ref": "#/definitions/DisplayInstallWarnings" - }, - "UnsupportedOSArchitectures": { - "$ref": "#/definitions/UnsupportedOSArchitectures" - }, - "UnsupportedArguments": { - "$ref": "#/definitions/UnsupportedArguments" - }, - "AppsAndFeaturesEntries": { - "$ref": "#/definitions/AppsAndFeaturesEntries" - }, - "ElevationRequirement": { - "$ref": "#/definitions/ElevationRequirement" - }, - "InstallationMetadata": { - "$ref": "#/definitions/InstallationMetadata" - }, - "DownloadCommandProhibited": { - "$ref": "#/definitions/DownloadCommandProhibited" - }, - "RepairBehavior": { - "$ref": "#/definitions/RepairBehavior" - }, - "ArchiveBinariesDependOnPath": { - "$ref": "#/definitions/ArchiveBinariesDependOnPath" - }, - "Authentication": { - "$ref": "#/definitions/Authentication" - }, - "UninstallerSwitches": { - "$ref": "#/definitions/UninstallerSwitches" - }, - "UninstallerSuccessCodes": { - "$ref": "#/definitions/UninstallerSuccessCodes" - } - }, - "required": [ - "Architecture", - "InstallerUrl", - "InstallerSha256" - ] + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" } - }, + }, + "required": [ + "Architecture", + "InstallerUrl", + "InstallerSha256" + ] + } + }, "type": "object", "properties": { "PackageIdentifier": { @@ -1099,12 +1099,6 @@ "InstallerSuccessCodes": { "$ref": "#/definitions/InstallerSuccessCodes" }, - "UninstallerSwitches": { - "$ref": "#/definitions/UninstallerSwitches" - }, - "UninstallerSuccessCodes": { - "$ref": "#/definitions/UninstallerSuccessCodes" - }, "ExpectedReturnCodes": { "$ref": "#/definitions/ExpectedReturnCodes" }, @@ -1180,6 +1174,12 @@ "Authentication": { "$ref": "#/definitions/Authentication" }, + "UninstallerSwitches": { + "$ref": "#/definitions/UninstallerSwitches" + }, + "UninstallerSuccessCodes": { + "$ref": "#/definitions/UninstallerSuccessCodes" + }, "Installers": { "type": "array", "items": {