diff --git a/doc/windows/package-manager/winget/returnCodes.md b/doc/windows/package-manager/winget/returnCodes.md index b37fbe5c6e..caad7a5ef4 100644 --- a/doc/windows/package-manager/winget/returnCodes.md +++ b/doc/windows/package-manager/winget/returnCodes.md @@ -160,8 +160,7 @@ ms.localizationpriority: medium | 0x8A150107 | -1978334969 | APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK | This application requires internet connectivity. Connect to a network then try again. | | 0x8A150108 | -1978334968 | APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT | This application encountered an error during installation. Contact support. | | 0x8A150109 | -1978334967 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH | Restart your PC to finish installation. | -| 0x8A15010A | -1978334966 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_INSTALL | -Installation failed. Restart your PC then try again. | +| 0x8A15010A | -1978334966 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_INSTALL | Installation failed. Restart your PC then try again. | | 0x8A15010B | -1978334965 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED | Your PC will restart to finish installation. | | 0x8A15010C | -1978334964 | APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER | You cancelled the installation. | | 0x8A15010D | -1978334963 | APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED | Another version of this application is already installed. | @@ -171,7 +170,8 @@ Installation failed. Restart your PC then try again. | | 0x8A150111 | -1978334959 | APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION | Application is currently in use by another application. | | 0x8A150112 | -1978334958 | APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER | Invalid parameter. | | 0x8A150113 | -1978334957 | APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED | Package not supported by the system. | -| 0x8A150114 | -1978334956 | APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED | The installer does not support upgrading an existing package. | +| 0x8A150114 | -1978334956 | APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED | The installer does not support upgrading an existing package. | +| 0x8A150115 | -1978334955 | APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR | Installation failed with installer custom error. | ## Check for package installed status diff --git a/schemas/JSON/manifests/v1.1.0/manifest.installer.1.1.0.json b/schemas/JSON/manifests/v1.1.0/manifest.installer.1.1.0.json index adf8ce8137..b750747056 100644 --- a/schemas/JSON/manifests/v1.1.0/manifest.installer.1.1.0.json +++ b/schemas/JSON/manifests/v1.1.0/manifest.installer.1.1.0.json @@ -179,7 +179,8 @@ "blockedByPolicy" ] } - } + }, + "required": [ "InstallerReturnCode", "ReturnResponse" ] }, "maxItems": 128, "description": "Installer exit codes for common errors" @@ -667,4 +668,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.1.0/manifest.singleton.1.1.0.json b/schemas/JSON/manifests/v1.1.0/manifest.singleton.1.1.0.json index 23249c22e3..03ad3db98a 100644 --- a/schemas/JSON/manifests/v1.1.0/manifest.singleton.1.1.0.json +++ b/schemas/JSON/manifests/v1.1.0/manifest.singleton.1.1.0.json @@ -212,7 +212,8 @@ "blockedByPolicy" ] } - } + }, + "required": [ "InstallerReturnCode", "ReturnResponse" ] }, "maxItems": 128, "description": "Installer exit codes for common errors" @@ -803,4 +804,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.2.0/manifest.installer.1.2.0.json b/schemas/JSON/manifests/v1.2.0/manifest.installer.1.2.0.json index a7fe40578f..d9758d46ce 100644 --- a/schemas/JSON/manifests/v1.2.0/manifest.installer.1.2.0.json +++ b/schemas/JSON/manifests/v1.2.0/manifest.installer.1.2.0.json @@ -200,9 +200,10 @@ }, "ReturnResponseUrl": { "$ref": "#/definitions/Url", - "description": "The return response url to provide additional guidance for expected return codes" + "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" @@ -710,4 +711,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.2.0/manifest.singleton.1.2.0.json b/schemas/JSON/manifests/v1.2.0/manifest.singleton.1.2.0.json index 90e4c4122c..b8cb13de2e 100644 --- a/schemas/JSON/manifests/v1.2.0/manifest.singleton.1.2.0.json +++ b/schemas/JSON/manifests/v1.2.0/manifest.singleton.1.2.0.json @@ -244,7 +244,8 @@ "$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" @@ -872,4 +873,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json b/schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json index 1c09ee9ae8..1ca938f73b 100644 --- a/schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json +++ b/schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json @@ -246,7 +246,8 @@ "$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" @@ -831,4 +832,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json b/schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json index cf0e9cc9b7..dcb636fd94 100644 --- a/schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json +++ b/schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json @@ -288,7 +288,8 @@ "$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" @@ -993,4 +994,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.5.0/manifest.defaultLocale.1.5.0.json b/schemas/JSON/manifests/v1.5.0/manifest.defaultLocale.1.5.0.json index d081e9e61a..d73503efc1 100644 --- a/schemas/JSON/manifests/v1.5.0/manifest.defaultLocale.1.5.0.json +++ b/schemas/JSON/manifests/v1.5.0/manifest.defaultLocale.1.5.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -275,4 +277,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.5.0/manifest.installer.1.5.0.json b/schemas/JSON/manifests/v1.5.0/manifest.installer.1.5.0.json index 16f2ad9a1d..833577565a 100644 --- a/schemas/JSON/manifests/v1.5.0/manifest.installer.1.5.0.json +++ b/schemas/JSON/manifests/v1.5.0/manifest.installer.1.5.0.json @@ -246,7 +246,8 @@ "$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" @@ -831,4 +832,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.5.0/manifest.locale.1.5.0.json b/schemas/JSON/manifests/v1.5.0/manifest.locale.1.5.0.json index bffd87e40f..4cdfaa86ad 100644 --- a/schemas/JSON/manifests/v1.5.0/manifest.locale.1.5.0.json +++ b/schemas/JSON/manifests/v1.5.0/manifest.locale.1.5.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -266,4 +268,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.5.0/manifest.singleton.1.5.0.json b/schemas/JSON/manifests/v1.5.0/manifest.singleton.1.5.0.json index 71afdd2750..0fcf710f03 100644 --- a/schemas/JSON/manifests/v1.5.0/manifest.singleton.1.5.0.json +++ b/schemas/JSON/manifests/v1.5.0/manifest.singleton.1.5.0.json @@ -73,7 +73,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -346,7 +348,8 @@ "$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" @@ -1058,4 +1061,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.6.0/manifest.defaultLocale.1.6.0.json b/schemas/JSON/manifests/v1.6.0/manifest.defaultLocale.1.6.0.json index 483403fcc6..b0a4d49563 100644 --- a/schemas/JSON/manifests/v1.6.0/manifest.defaultLocale.1.6.0.json +++ b/schemas/JSON/manifests/v1.6.0/manifest.defaultLocale.1.6.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -275,4 +277,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.6.0/manifest.installer.1.6.0.json b/schemas/JSON/manifests/v1.6.0/manifest.installer.1.6.0.json index 91464f817a..5d268259b9 100644 --- a/schemas/JSON/manifests/v1.6.0/manifest.installer.1.6.0.json +++ b/schemas/JSON/manifests/v1.6.0/manifest.installer.1.6.0.json @@ -246,7 +246,8 @@ "$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" @@ -842,4 +843,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.6.0/manifest.locale.1.6.0.json b/schemas/JSON/manifests/v1.6.0/manifest.locale.1.6.0.json index 2374071390..b281b91e9c 100644 --- a/schemas/JSON/manifests/v1.6.0/manifest.locale.1.6.0.json +++ b/schemas/JSON/manifests/v1.6.0/manifest.locale.1.6.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -266,4 +268,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.6.0/manifest.singleton.1.6.0.json b/schemas/JSON/manifests/v1.6.0/manifest.singleton.1.6.0.json index 1567d0e165..83ae462983 100644 --- a/schemas/JSON/manifests/v1.6.0/manifest.singleton.1.6.0.json +++ b/schemas/JSON/manifests/v1.6.0/manifest.singleton.1.6.0.json @@ -73,7 +73,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -346,7 +348,8 @@ "$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" @@ -1069,4 +1072,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.7.0/manifest.defaultLocale.1.7.0.json b/schemas/JSON/manifests/v1.7.0/manifest.defaultLocale.1.7.0.json index 4ce2e8b3fe..424024c2fd 100644 --- a/schemas/JSON/manifests/v1.7.0/manifest.defaultLocale.1.7.0.json +++ b/schemas/JSON/manifests/v1.7.0/manifest.defaultLocale.1.7.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -275,4 +277,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.7.0/manifest.installer.1.7.0.json b/schemas/JSON/manifests/v1.7.0/manifest.installer.1.7.0.json index cfbf745ea6..4940acb829 100644 --- a/schemas/JSON/manifests/v1.7.0/manifest.installer.1.7.0.json +++ b/schemas/JSON/manifests/v1.7.0/manifest.installer.1.7.0.json @@ -252,7 +252,8 @@ "$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" @@ -863,4 +864,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.7.0/manifest.locale.1.7.0.json b/schemas/JSON/manifests/v1.7.0/manifest.locale.1.7.0.json index 8f0de08745..2c5c6903ce 100644 --- a/schemas/JSON/manifests/v1.7.0/manifest.locale.1.7.0.json +++ b/schemas/JSON/manifests/v1.7.0/manifest.locale.1.7.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -266,4 +268,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.7.0/manifest.singleton.1.7.0.json b/schemas/JSON/manifests/v1.7.0/manifest.singleton.1.7.0.json index 7e1678e1b0..15781b3950 100644 --- a/schemas/JSON/manifests/v1.7.0/manifest.singleton.1.7.0.json +++ b/schemas/JSON/manifests/v1.7.0/manifest.singleton.1.7.0.json @@ -73,7 +73,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -352,7 +354,8 @@ "$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" @@ -1090,4 +1093,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.9.0/manifest.defaultLocale.1.9.0.json b/schemas/JSON/manifests/v1.9.0/manifest.defaultLocale.1.9.0.json index 2aa7a504ab..5b71ed19e6 100644 --- a/schemas/JSON/manifests/v1.9.0/manifest.defaultLocale.1.9.0.json +++ b/schemas/JSON/manifests/v1.9.0/manifest.defaultLocale.1.9.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -275,4 +277,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.9.0/manifest.installer.1.9.0.json b/schemas/JSON/manifests/v1.9.0/manifest.installer.1.9.0.json index a5b00edc5e..89aaca4281 100644 --- a/schemas/JSON/manifests/v1.9.0/manifest.installer.1.9.0.json +++ b/schemas/JSON/manifests/v1.9.0/manifest.installer.1.9.0.json @@ -252,7 +252,8 @@ "$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" diff --git a/schemas/JSON/manifests/v1.9.0/manifest.locale.1.9.0.json b/schemas/JSON/manifests/v1.9.0/manifest.locale.1.9.0.json index 7cf6502d51..96600dd5a2 100644 --- a/schemas/JSON/manifests/v1.9.0/manifest.locale.1.9.0.json +++ b/schemas/JSON/manifests/v1.9.0/manifest.locale.1.9.0.json @@ -55,7 +55,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -266,4 +268,4 @@ "ManifestType", "ManifestVersion" ] -} \ No newline at end of file +} diff --git a/schemas/JSON/manifests/v1.9.0/manifest.singleton.1.9.0.json b/schemas/JSON/manifests/v1.9.0/manifest.singleton.1.9.0.json index 223ac8343d..36b33528b4 100644 --- a/schemas/JSON/manifests/v1.9.0/manifest.singleton.1.9.0.json +++ b/schemas/JSON/manifests/v1.9.0/manifest.singleton.1.9.0.json @@ -73,7 +73,9 @@ "type": "object", "properties": { "IconUrl": { - "$ref": "#/definitions/Url", + "type": "string", + "pattern": "^([Hh][Tt][Tt][Pp][Ss]?)://.+$", + "maxLength": 2048, "description": "The url of the hosted icon file" }, "IconFileType": { @@ -352,7 +354,8 @@ "$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" diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h index 5aa7616509..87abb44340 100644 --- a/src/AppInstallerCLICore/Resources.h +++ b/src/AppInstallerCLICore/Resources.h @@ -325,6 +325,7 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeBlockedByPolicy); WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeCancelledByUser); WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeContactSupport); + WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeCustomError); WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeDiskFull); WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeDowngrade); WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeFileInUse); diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp index 8f7081fa13..e85540c379 100644 --- a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp @@ -145,6 +145,8 @@ namespace AppInstaller::CLI::Workflow return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY, Resource::String::InstallFlowReturnCodeBlockedByPolicy); case ExpectedReturnCodeEnum::SystemNotSupported: return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, Resource::String::InstallFlowReturnCodeSystemNotSupported); + case ExpectedReturnCodeEnum::Custom: + return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR, Resource::String::InstallFlowReturnCodeCustomError); default: THROW_HR(E_UNEXPECTED); } @@ -501,7 +503,7 @@ namespace AppInstaller::CLI::Workflow if (FAILED(terminationHR)) { context.Reporter.Error() << returnCode.Message << std::endl; - auto returnResponseUrl = expectedReturnCodeItr->second.ReturnResponseUrl; + const auto& returnResponseUrl = expectedReturnCodeItr->second.ReturnResponseUrl; if (!returnResponseUrl.empty()) { context.Reporter.Error() << Resource::String::RelatedLink << ' ' << returnResponseUrl << std::endl; diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index 46d093b80c..e2c98bbf6d 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -1284,6 +1284,9 @@ Do you agree to the terms? The current system configuration does not support the installation of this package. + + Installation failed with a custom installer error. Contact package support. + Installation abandoned @@ -2521,6 +2524,9 @@ Please specify one of them using the --source option to proceed. The installer does not support upgrading an existing package. + + Installation failed with a custom installer error. + The Apps and Features Entry for the package could not be found. @@ -3174,4 +3180,4 @@ Please specify one of them using the --source option to proceed. Version - \ No newline at end of file + diff --git a/src/AppInstallerCLITests/YamlManifest.cpp b/src/AppInstallerCLITests/YamlManifest.cpp index deaa572c64..33b448c79c 100644 --- a/src/AppInstallerCLITests/YamlManifest.cpp +++ b/src/AppInstallerCLITests/YamlManifest.cpp @@ -1373,6 +1373,20 @@ TEST_CASE("WriteManifestWithMultipleLocale", "[ManifestCreation]") REQUIRE(generatedManifest.Localizations.size() == 2); } +TEST_CASE("WriteManifestWithMSStoreInstaller", "[ManifestCreation]") +{ + Manifest msstoreManifest = YamlParser::CreateFromPath(TestDataFile("DownloadFlowTest_MSStore.yaml")); + TempDirectory exportedDirectory{ "exported" }; + std::filesystem::path generatedManifestPath = exportedDirectory.GetPath() / "testManifestWithMultipleLocale.yaml"; + msstoreManifest.ManifestVersion = ManifestVer{ "1.1.0" }; + YamlWriter::OutputYamlFile(msstoreManifest, msstoreManifest.Installers[0], generatedManifestPath); + + REQUIRE(std::filesystem::exists(generatedManifestPath)); + Manifest generatedManifest = YamlParser::CreateFromPath(generatedManifestPath); + REQUIRE(generatedManifest.Installers[0].BaseInstallerType == InstallerTypeEnum::MSStore); + REQUIRE(!generatedManifest.Installers[0].ProductId.empty()); +} + YamlManifestInfo CreateYamlManifestInfo(std::string testDataFile) { YamlManifestInfo result; diff --git a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp index 51379004da..ce448c09f9 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp @@ -310,6 +310,8 @@ namespace AppInstaller::Manifest { "InstallerUrl", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Url = value.as(); return {}; } }, { "InstallerSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, { "SignatureSha256", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as()); return {}; } }, + // No custom validation needed at field populating time since we have semantic validation later to block msstore and productId from community repo. + { "MSStoreProductIdentifier", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr(v)->ProductId = value.as(); return {}; } }, }; std::move(v1InstallerFields.begin(), v1InstallerFields.end(), std::inserter(result, result.end())); diff --git a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp index 92f23dcbc1..62bd3f8d2a 100644 --- a/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp +++ b/src/AppInstallerCommonCore/Manifest/YamlWriter.cpp @@ -150,6 +150,22 @@ namespace AppInstaller::Manifest::YamlWriter { \ WRITE_PROPERTY(emitter, key, value) \ } \ + } + +#define WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(emitter, key, field) \ + { \ + if (!field.empty()) \ + { \ + WRITE_PROPERTY(emitter, key, Utility::SHA256::ConvertToString(field)) \ + } \ + } + +#define WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(emitter, key, value, enumField, enumType) \ + { \ + if (enumField != enumType::Unknown) \ + { \ + WRITE_PROPERTY(emitter, key, value) \ + } \ } void ProcessAgreements(YAML::Emitter& out, const std::vector& agreements) @@ -203,18 +219,18 @@ namespace AppInstaller::Manifest::YamlWriter for (const auto& icon : icons) { out << YAML::BeginMap; - WRITE_PROPERTY_IF_EXISTS(out, IconUrl, icon.Url); - WRITE_PROPERTY_IF_EXISTS(out, IconFileType, IconFileTypeToString(icon.FileType)); - WRITE_PROPERTY_IF_EXISTS(out, IconResolution, IconResolutionToString(icon.Resolution)); - WRITE_PROPERTY_IF_EXISTS(out, IconTheme, IconThemeToString(icon.Theme)); - WRITE_PROPERTY_IF_EXISTS(out, IconSha256, Utility::LocIndString{ Utility::SHA256::ConvertToString(icon.Sha256)}); + WRITE_PROPERTY(out, IconUrl, icon.Url); + WRITE_PROPERTY(out, IconFileType, IconFileTypeToString(icon.FileType)); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, IconResolution, IconResolutionToString(icon.Resolution), icon.Resolution, IconResolutionEnum); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, IconTheme, IconThemeToString(icon.Theme), icon.Theme, IconThemeEnum); + WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, IconSha256, icon.Sha256); out << YAML::EndMap; } out << YAML::EndSeq; } // Generic method for handling a list of strings (i.e. tags) - void ProcessSequence(YAML::Emitter& out, std::string_view name, std::vector items) + void ProcessStringSequence(YAML::Emitter& out, std::string_view name, std::vector items) { if (items.empty()) { @@ -224,8 +240,11 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << name; out << YAML::BeginSeq; for (const auto& item : items) - { - out << item; + { + if (!item.empty()) + { + out << item; + } } out << YAML::EndSeq; } @@ -235,7 +254,7 @@ namespace AppInstaller::Manifest::YamlWriter ProcessAgreements(out, manifest.Get()); ProcessDocumentations(out, manifest.Get()); ProcessIcons(out, manifest.Get()); - ProcessSequence(out, Tags, manifest.Get()); + ProcessStringSequence(out, Tags, manifest.Get()); WRITE_PROPERTY(out, PackageLocale, manifest.Locale); WRITE_PROPERTY_IF_EXISTS(out, Author, manifest.Get()); @@ -271,12 +290,7 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::BeginMap; WRITE_PROPERTY_IF_EXISTS(out, DisplayName, appsAndFeatureEntry.DisplayName); WRITE_PROPERTY_IF_EXISTS(out, DisplayVersion, appsAndFeatureEntry.DisplayVersion); - - if (appsAndFeatureEntry.InstallerType != InstallerTypeEnum::Unknown) - { - WRITE_PROPERTY(out, InstallerType, InstallerTypeToString(appsAndFeatureEntry.InstallerType)); - } - + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, InstallerType, InstallerTypeToString(appsAndFeatureEntry.InstallerType), appsAndFeatureEntry.InstallerType, InstallerTypeEnum); WRITE_PROPERTY_IF_EXISTS(out, ProductCode, appsAndFeatureEntry.ProductCode); WRITE_PROPERTY_IF_EXISTS(out, Publisher, appsAndFeatureEntry.Publisher); WRITE_PROPERTY_IF_EXISTS(out, UpgradeCode, appsAndFeatureEntry.UpgradeCode); @@ -313,8 +327,8 @@ namespace AppInstaller::Manifest::YamlWriter for (const auto& expectedReturnCode : expectedReturnCodes) { out << YAML::BeginMap; - WRITE_PROPERTY_IF_EXISTS(out, InstallerReturnCode, std::to_string(expectedReturnCode.first)); - WRITE_PROPERTY_IF_EXISTS(out, ReturnResponse, ExpectedReturnCodeToString(expectedReturnCode.second.ReturnResponseEnum)); + WRITE_PROPERTY(out, InstallerReturnCode, std::to_string(expectedReturnCode.first)); + WRITE_PROPERTY(out, ReturnResponse, ExpectedReturnCodeToString(expectedReturnCode.second.ReturnResponseEnum)); WRITE_PROPERTY_IF_EXISTS(out, ReturnResponseUrl, expectedReturnCode.second.ReturnResponseUrl); out << YAML::EndMap; } @@ -330,9 +344,12 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << UnsupportedArguments; out << YAML::BeginSeq; - for (auto const& unsupportedArgs : unsupportedArguments) + for (auto const& unsupportedArg : unsupportedArguments) { - out << UnsupportedArgumentToString(unsupportedArgs); + if (unsupportedArg != UnsupportedArgumentEnum::Unknown) + { + out << UnsupportedArgumentToString(unsupportedArg); + } } out << YAML::EndSeq; } @@ -347,8 +364,11 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << UnsupportedOSArchitectures; out << YAML::BeginSeq; for (auto const& architecture : architectures) - { - out << Utility::ToLower(ToString(architecture)); + { + if (architecture != AppInstaller::Utility::Architecture::Unknown) + { + out << Utility::ToLower(ToString(architecture)); + } } out << YAML::EndSeq; } @@ -363,8 +383,11 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << InstallModes; out << YAML::BeginSeq; for (auto const& installMode : installModes) - { - out << InstallModeToString(installMode); + { + if (installMode != InstallModeEnum::Unknown) + { + out << InstallModeToString(installMode); + } } out << YAML::EndSeq; } @@ -378,8 +401,11 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << Platform; out << YAML::BeginSeq; for (auto const& platform : platforms) - { - out << PlatformToString(platform); + { + if (platform != PlatformEnum::Unknown) + { + out << PlatformToString(platform); + } } out << YAML::EndSeq; } @@ -409,8 +435,8 @@ namespace AppInstaller::Manifest::YamlWriter out << YAML::Key << Markets; out << YAML::BeginMap; - ProcessSequence(out, AllowedMarkets, marketsInfo.AllowedMarkets); - ProcessSequence(out, ExcludedMarkets, marketsInfo.ExcludedMarkets); + ProcessStringSequence(out, AllowedMarkets, marketsInfo.AllowedMarkets); + ProcessStringSequence(out, ExcludedMarkets, marketsInfo.ExcludedMarkets); out << YAML::EndMap; } @@ -426,7 +452,7 @@ namespace AppInstaller::Manifest::YamlWriter for (const auto& nestedInstallerFile : nestedInstallerFiles) { out << YAML::BeginMap; - WRITE_PROPERTY_IF_EXISTS(out, NestedInstallerFileRelativeFilePath, nestedInstallerFile.RelativeFilePath); + WRITE_PROPERTY(out, NestedInstallerFileRelativeFilePath, nestedInstallerFile.RelativeFilePath); WRITE_PROPERTY_IF_EXISTS(out, PortableCommandAlias, nestedInstallerFile.PortableCommandAlias); out << YAML::EndMap; } @@ -445,9 +471,9 @@ namespace AppInstaller::Manifest::YamlWriter for (const auto& installedFile : installedFiles) { out << YAML::BeginMap; - WRITE_PROPERTY_IF_EXISTS(out, InstallationMetadataRelativeFilePath, installedFile.RelativeFilePath); - WRITE_PROPERTY_IF_EXISTS(out, FileSha256, Utility::LocIndString{ Utility::SHA256::ConvertToString(installedFile.FileSha256) }); - WRITE_PROPERTY_IF_EXISTS(out, FileType, InstalledFileTypeToString(installedFile.FileType)); + WRITE_PROPERTY(out, InstallationMetadataRelativeFilePath, installedFile.RelativeFilePath); + WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, FileSha256, installedFile.FileSha256); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, FileType, InstalledFileTypeToString(installedFile.FileType), installedFile.FileType, InstalledFileTypeEnum); WRITE_PROPERTY_IF_EXISTS(out, InvocationParameter, installedFile.InvocationParameter); WRITE_PROPERTY_IF_EXISTS(out, DisplayName, installedFile.DisplayName); @@ -509,7 +535,7 @@ namespace AppInstaller::Manifest::YamlWriter dependencies.ApplyToType(DependencyType::Package, [&out](Dependency dependency) { out << YAML::BeginMap; - WRITE_PROPERTY_IF_EXISTS(out, PackageIdentifier, dependency.Id()); + WRITE_PROPERTY(out, PackageIdentifier, dependency.Id()); if (dependency.MinVersion.has_value()) { @@ -539,30 +565,15 @@ namespace AppInstaller::Manifest::YamlWriter { WRITE_PROPERTY(out, Architecture, Utility::ToLower(ToString(installer.Arch))); WRITE_PROPERTY(out, InstallerType, InstallerTypeToString(installer.BaseInstallerType)); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, NestedInstallerType, InstallerTypeToString(installer.NestedInstallerType), installer.NestedInstallerType, InstallerTypeEnum); + WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, InstallerSha256, installer.Sha256); + WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, SignatureSha256, installer.SignatureSha256); + WRITE_PROPERTY_IF_EXISTS(out, InstallerUrl, installer.Url); + WRITE_PROPERTY_IF_EXISTS(out, MSStoreProductIdentifier, installer.ProductId); - if (installer.NestedInstallerType != InstallerTypeEnum::Unknown) - { - WRITE_PROPERTY(out, NestedInstallerType, InstallerTypeToString(installer.NestedInstallerType)); - } - - if (!installer.Sha256.empty()) - { - WRITE_PROPERTY(out, InstallerSha256, Utility::SHA256::ConvertToString(installer.Sha256)); - } - - if (!installer.SignatureSha256.empty()) - { - WRITE_PROPERTY(out, SignatureSha256, Utility::SHA256::ConvertToString(installer.SignatureSha256)); - } - WRITE_PROPERTY_IF_EXISTS(out, InstallerUrl, installer.Url); - WRITE_PROPERTY_IF_EXISTS(out, Scope, Utility::ToLower(ScopeToString(installer.Scope))); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, Scope, Utility::ToLower(ScopeToString(installer.Scope)), installer.Scope, ScopeEnum); WRITE_PROPERTY_IF_EXISTS(out, InstallerLocale, installer.Locale); - - if (installer.ElevationRequirement != ElevationRequirementEnum::Unknown) - { - WRITE_PROPERTY(out, ElevationRequirement, ElevationRequirementToString(installer.ElevationRequirement)); - } - + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, ElevationRequirement, ElevationRequirementToString(installer.ElevationRequirement), installer.ElevationRequirement, ElevationRequirementEnum); WRITE_PROPERTY_IF_EXISTS(out, PackageFamilyName, installer.PackageFamilyName); WRITE_PROPERTY_IF_EXISTS(out, ReleaseDate, installer.ReleaseDate); WRITE_BOOL_PROPERTY(out, InstallerAbortsTerminal, installer.InstallerAbortsTerminal); @@ -573,14 +584,14 @@ namespace AppInstaller::Manifest::YamlWriter WRITE_BOOL_PROPERTY(out, ArchiveBinariesDependOnPath, installer.ArchiveBinariesDependOnPath); WRITE_PROPERTY_IF_EXISTS(out, MinimumOSVersion, installer.MinOSVersion); WRITE_PROPERTY_IF_EXISTS(out, ProductCode, installer.ProductCode); - WRITE_PROPERTY_IF_EXISTS(out, UpgradeBehavior, UpdateBehaviorToString(installer.UpdateBehavior)); - WRITE_PROPERTY_IF_EXISTS(out, RepairBehavior, RepairBehaviorToString(installer.RepairBehavior)); - - ProcessSequence(out, Capabilities, installer.Capabilities); - ProcessSequence(out, Commands, installer.Commands); - ProcessSequence(out, FileExtensions, installer.FileExtensions); - ProcessSequence(out, Protocols, installer.Protocols); - ProcessSequence(out, RestrictedCapabilities, installer.RestrictedCapabilities); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, UpgradeBehavior, UpdateBehaviorToString(installer.UpdateBehavior), installer.UpdateBehavior, UpdateBehaviorEnum); + WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, RepairBehavior, RepairBehaviorToString(installer.RepairBehavior), installer.RepairBehavior, RepairBehaviorEnum); + + ProcessStringSequence(out, Capabilities, installer.Capabilities); + ProcessStringSequence(out, Commands, installer.Commands); + ProcessStringSequence(out, FileExtensions, installer.FileExtensions); + ProcessStringSequence(out, Protocols, installer.Protocols); + ProcessStringSequence(out, RestrictedCapabilities, installer.RestrictedCapabilities); ProcessAppsAndFeaturesEntries(out, installer.AppsAndFeaturesEntries); ProcessDependencies(out, installer.Dependencies); diff --git a/src/AppInstallerSharedLib/Errors.cpp b/src/AppInstallerSharedLib/Errors.cpp index 87f63ab9ac..73e81ef12e 100644 --- a/src/AppInstallerSharedLib/Errors.cpp +++ b/src/AppInstallerSharedLib/Errors.cpp @@ -244,6 +244,7 @@ namespace AppInstaller WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER, "Invalid parameter."), WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, "Package not supported by the system."), WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED, "The installer does not support upgrading an existing package."), + WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR, "Installation failed with a custom installer error."), // Status values for check package installed status results. // Partial success has the success bit(first bit) set to 0. diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h index d00bc8a18a..3524d812bf 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -174,6 +174,7 @@ #define APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER ((HRESULT)0x8A150112) #define APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED ((HRESULT)0x8A150113) #define APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED ((HRESULT)0x8A150114) +#define APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR ((HRESULT)0x8A150115) // Status values for check package installed status results. // Partial success has the success bit(first bit) set to 0. diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 607a427082..ecff759994 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -384,6 +384,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif if (manifestVersion >= TestManifestVersion.V190) { Assert.False(installer1.ArchiveBinariesDependOnPath); + Assert.Equal("fakeIdentifier", installer2.ProductId); } // Additional Localizations diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml index 28e92896a4..3bf371df37 100644 --- a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml @@ -246,6 +246,7 @@ Installers: InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe InstallerType: exe - ProductCode: '{Bar}' + ProductCode: '{Bar}' + MSStoreProductIdentifier: fakeIdentifier ManifestType: merged -ManifestVersion: 1.7.0 \ No newline at end of file +ManifestVersion: 1.7.0 diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs index 534d29af4a..811081064c 100644 --- a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs +++ b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -278,17 +278,17 @@ public class Manifest /// /// Gets or sets a value indicating whether the default installer behavior aborts terminal. /// - public bool InstallerAbortsTerminal { get; set; } + public bool? InstallerAbortsTerminal { get; set; } /// /// Gets or sets a value indicating whether the default installer behavior requires explicit install location. /// - public bool InstallLocationRequired { get; set; } + public bool? InstallLocationRequired { get; set; } /// /// Gets or sets a value indicating whether the default installer behavior requires explicit upgrade. /// - public bool RequireExplicitUpgrade { get; set; } + public bool? RequireExplicitUpgrade { get; set; } /// /// Gets or sets the default installer release date. @@ -303,7 +303,7 @@ public class Manifest /// /// Gets or sets a value indicating whether to display install warnings. /// - public bool DisplayInstallWarnings { get; set; } + public bool? DisplayInstallWarnings { get; set; } /// /// Gets or sets the default list of apps and features entries. @@ -318,33 +318,33 @@ public class Manifest /// /// Gets or sets the default list of installer expected return codes. /// - public List ExpectedReturnCodes { get; set; } - - /// - /// Gets or sets collection of ManifestInstaller. At least one is required. - /// - public List Installers { get; set; } - - /// - /// Gets or sets collection of additional ManifestLocalization. - /// - public List Localization { get; set; } - + public List ExpectedReturnCodes { get; set; } + /// /// Gets or sets a value indicating whether the installer is prohibited from being downloaded for offline installation. /// - public bool DownloadCommandProhibited { get; set; } + public bool? DownloadCommandProhibited { get; set; } /// /// Gets or sets a value indicating whether the install location should be added directly to the PATH environment variable. /// - public bool ArchiveBinariesDependOnPath { get; set; } + public bool? ArchiveBinariesDependOnPath { get; set; } /// /// Gets or sets the default repair behavior. /// public string RepairBehavior { get; set; } + /// + /// Gets or sets collection of ManifestInstaller. At least one is required. + /// + public List Installers { get; set; } + + /// + /// Gets or sets collection of additional ManifestLocalization. + /// + public List Localization { get; set; } + /// /// Deserialize a stream reader into a Manifest object. /// diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs index 1f84a1da04..c6e326e3e3 100644 --- a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs +++ b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs @@ -35,7 +35,15 @@ public class ManifestInstaller /// /// Gets or sets the signature SHA256 for an appx/msix. Only used by appx/msix type. /// - public string SignatureSha256 { get; set; } + public string SignatureSha256 { get; set; } + + /// + /// Gets or sets the Store ProductId. Only used when InstallerType is MSStore. + /// + [YamlMember(Alias = "MSStoreProductIdentifier")] + public string ProductId { get; set; } + + // Common installer fields that may have defaults in manifest root level. /// /// Gets or sets the installer locale. @@ -131,17 +139,17 @@ public class ManifestInstaller /// /// Gets or sets a value indicating whether the installer behavior aborts terminal. /// - public bool InstallerAbortsTerminal { get; set; } + public bool? InstallerAbortsTerminal { get; set; } /// /// Gets or sets a value indicating whether the installer behavior requires explicit install location. /// - public bool InstallLocationRequired { get; set; } + public bool? InstallLocationRequired { get; set; } /// /// Gets or sets a value indicating whether the installer behavior requires explicit upgrade. /// - public bool RequireExplicitUpgrade { get; set; } + public bool? RequireExplicitUpgrade { get; set; } /// /// Gets or sets the installer release date. @@ -191,17 +199,17 @@ public class ManifestInstaller /// /// Gets or sets a value indicating whether to display install warnings. /// - public bool DisplayInstallWarnings { get; set; } + public bool? DisplayInstallWarnings { get; set; } /// /// Gets or sets a value indicating whether the installer is prohibited from being downloaded for offline installation. /// - public bool DownloadCommandProhibited { get; set; } + public bool? DownloadCommandProhibited { get; set; } /// /// Gets or sets a value indicating whether the install location should be added directly to the PATH environment variable. /// - public bool ArchiveBinariesDependOnPath { get; set; } + public bool? ArchiveBinariesDependOnPath { get; set; } /// /// Gets or sets the repair behavior.