diff --git a/src/WingetCreateCore/Common/PackageParser.cs b/src/WingetCreateCore/Common/PackageParser.cs index 4220d314..051128b2 100644 --- a/src/WingetCreateCore/Common/PackageParser.cs +++ b/src/WingetCreateCore/Common/PackageParser.cs @@ -245,13 +245,20 @@ public static void UpdateInstallerNodesAsync(List installerMe // Update DisplayVersion for each AppsAndFeaturesEntry if (!string.IsNullOrEmpty(installerUpdate.DisplayVersion)) { - newInstaller.AppsAndFeaturesEntries = new List + if (newInstaller.AppsAndFeaturesEntries != null) { - new AppsAndFeaturesEntry + newInstaller.AppsAndFeaturesEntries[0].DisplayVersion = installerUpdate.DisplayVersion; + } + else + { + newInstaller.AppsAndFeaturesEntries = new List { - DisplayVersion = installerUpdate.DisplayVersion, - }, - }; + new AppsAndFeaturesEntry + { + DisplayVersion = installerUpdate.DisplayVersion, + }, + }; + } } // if the installerUpdate does not have a binary or url architecture specified, then just use what is specified in the installer. @@ -477,21 +484,36 @@ private static void UpdateInstallerMetadata(Installer existingInstaller, Install if (existingInstaller.AppsAndFeaturesEntries != null && newInstaller.AppsAndFeaturesEntries != null) { - // When --display-version is provided, AppsAndFeaturesEntries for the new installer will not be null - // and will contain a single entry. - string newDisplayVersion = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().DisplayVersion; - - // Set DisplayVersion for each new installer if it exists in the corresponding existing installer. foreach (var existingAppsAndFeaturesEntry in existingInstaller.AppsAndFeaturesEntries) { - if (existingAppsAndFeaturesEntry.DisplayVersion != null) + if (existingAppsAndFeaturesEntry.DisplayName != null && newInstaller.AppsAndFeaturesEntries.FirstOrDefault().DisplayName != null) { - existingAppsAndFeaturesEntry.DisplayVersion = newDisplayVersion ?? existingAppsAndFeaturesEntry.DisplayVersion; + existingAppsAndFeaturesEntry.DisplayName = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().DisplayName; + } - // Break on first match to avoid setting DisplayVersion for all entries. - // We do not support updating multiple DisplayVersions under the same installer. - break; + if (existingAppsAndFeaturesEntry.DisplayVersion != null && newInstaller.AppsAndFeaturesEntries.FirstOrDefault().DisplayVersion != null) + { + existingAppsAndFeaturesEntry.DisplayVersion = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().DisplayVersion; + } + + if (existingAppsAndFeaturesEntry.Publisher != null && newInstaller.AppsAndFeaturesEntries.FirstOrDefault().Publisher != null) + { + existingAppsAndFeaturesEntry.Publisher = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().Publisher; } + + if (existingAppsAndFeaturesEntry.ProductCode != null && newInstaller.AppsAndFeaturesEntries.FirstOrDefault().ProductCode != null) + { + existingAppsAndFeaturesEntry.ProductCode = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().ProductCode; + } + + if (existingAppsAndFeaturesEntry.UpgradeCode != null && newInstaller.AppsAndFeaturesEntries.FirstOrDefault().UpgradeCode != null) + { + existingAppsAndFeaturesEntry.UpgradeCode = newInstaller.AppsAndFeaturesEntries.FirstOrDefault().UpgradeCode; + } + + // Break on first match to avoid setting DisplayVersion for all entries. + // We do not support updating multiple DisplayVersions under the same installer. + break; } } } @@ -891,6 +913,17 @@ private static bool ParseMsi(string path, Installer baseInstaller, Manifests man } baseInstaller.ProductCode = properties.FirstOrDefault(p => p.Property == "ProductCode")?.Value; + baseInstaller.AppsAndFeaturesEntries = new List + { + new AppsAndFeaturesEntry + { + DisplayName = properties.FirstOrDefault(p => p.Property == "ProductName")?.Value, + DisplayVersion = properties.FirstOrDefault(p => p.Property == "ProductVersion")?.Value, + Publisher = properties.FirstOrDefault(p => p.Property == "Manufacturer")?.Value, + ProductCode = properties.FirstOrDefault(p => p.Property == "ProductCode")?.Value, + UpgradeCode = properties.FirstOrDefault(p => p.Property == "UpgradeCode")?.Value, + }, + }; string archString = database.SummaryInfo.Template.Split(';').First(); diff --git a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml index d384a7fd..2b779888 100644 --- a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml +++ b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml @@ -17,11 +17,7 @@ NestedInstallerFiles: - RelativeFilePath: WingetCreateTestExeInstaller.exe PortableCommandAlias: TestExeAlias AppsAndFeaturesEntries: -- DisplayName: TestDisplayName1 - Publisher: TestPublisher1 - DisplayVersion: 1.0.1 - ProductCode: TestProductCode1 - UpgradeCode: TestUpgradeCode1 +- DisplayVersion: 1.0.1 InstallerType: msi InstallerSwitches: Silent: /silent1 @@ -89,11 +85,7 @@ Installers: - RelativeFilePath: WingetCreateTestMsiInstaller.msi PortableCommandAlias: TestMsiAlias AppsAndFeaturesEntries: - - DisplayName: TestDisplayName2 - Publisher: TestPublisher2 - DisplayVersion: 1.0.2 - ProductCode: TestProductCode2 - UpgradeCode: TestUpgradeCode2 + - DisplayVersion: 1.0.2 InstallerType: exe InstallerSwitches: Silent: /silent2 diff --git a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs index 9946de5f..5a0d092f 100644 --- a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs +++ b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs @@ -1535,7 +1535,7 @@ public async Task UpdateRetainsNonNullInstallerFields() { TestUtils.InitializeMockDownloads(TestConstants.TestZipInstaller); string installerUrl = $"https://fakedomain.com/{TestConstants.TestZipInstaller}"; - (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.RetainInstallerFields", null, this.tempPath, new[] { $"{installerUrl}|x64", $"{installerUrl}|x86" }); + (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.RetainInstallerFields", null, this.tempPath, new[] { $"{installerUrl}|x64|1.0.1", $"{installerUrl}|x86|1.0.2" }); var updatedManifests = await RunUpdateCommand(command, initialManifestContent); ClassicAssert.IsNotNull(updatedManifests, "Command should have succeeded"); @@ -1561,7 +1561,7 @@ public async Task UpdateRetainsNonNullInstallerFields() ClassicAssert.IsNotNull(firstInstaller.Dependencies, "Dependencies for the first installer should not be null"); ClassicAssert.IsTrue(firstInstaller.Dependencies.PackageDependencies[0].PackageIdentifier == "TestPackageDependency1", "PackageDependencies PackageIdentifier for the first installer should be copied over from root"); ClassicAssert.IsNotNull(firstInstaller.AppsAndFeaturesEntries, "AppsAndFeaturesEntries for the first installer should not be null"); - ClassicAssert.IsTrue(firstInstaller.AppsAndFeaturesEntries[0].ProductCode == "TestProductCode1", "AppsAndFeaturesEntries ProductCode for the first installer should be copied over from root"); + ClassicAssert.IsTrue(firstInstaller.AppsAndFeaturesEntries[0].DisplayVersion == "1.0.1", "AppsAndFeaturesEntries DisplayVersion for the first installer should be copied over from root"); ClassicAssert.IsNotNull(firstInstaller.Platform, "Platform for the first installer should not be null"); ClassicAssert.IsTrue(firstInstaller.Platform[0] == Platform.Windows_Desktop, "Platform for the first installer should be copied over from root"); ClassicAssert.IsNotNull(firstInstaller.ExpectedReturnCodes, "ExpectedReturnCodes for the first installer should not be null"); @@ -1602,7 +1602,7 @@ public async Task UpdateRetainsNonNullInstallerFields() ClassicAssert.IsNotNull(secondInstaller.Dependencies, "Dependencies for the second installer should not be null"); ClassicAssert.IsTrue(secondInstaller.Dependencies.PackageDependencies[0].PackageIdentifier == "TestPackageDependency2", "PackageDependencies PackageIdentifier for the second installer should be preserved"); ClassicAssert.IsNotNull(secondInstaller.AppsAndFeaturesEntries, "AppsAndFeaturesEntries for the second installer should not be null"); - ClassicAssert.IsTrue(secondInstaller.AppsAndFeaturesEntries[0].ProductCode == "TestProductCode2", "AppsAndFeaturesEntries ProductCode for the second installer should be preserved"); + ClassicAssert.IsTrue(secondInstaller.AppsAndFeaturesEntries[0].DisplayVersion == "1.0.2", "AppsAndFeaturesEntries DisplayVersion for the second installer should be preserved"); ClassicAssert.IsNotNull(secondInstaller.Platform, "Platform for the second installer should not be null"); ClassicAssert.IsTrue(secondInstaller.Platform[0] == Platform.Windows_Universal, "Platform for the second installer should be preserved"); ClassicAssert.IsNotNull(secondInstaller.ExpectedReturnCodes, "ExpectedReturnCodes for the second installer should not be null");