diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2020-07-19 15:05:27 +1000 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2020-07-19 19:19:36 +1000 |
| commit | 2a87b3e728fb56202d21d402cecc0bceeac49ade (patch) | |
| tree | cf74ce123fc184aae60a2e0bdffaa958895ef245 /src | |
| parent | f4cefb9ac9a6911ee0a1ad035e6ee50b7f28e5c5 (diff) | |
| download | wix-2a87b3e728fb56202d21d402cecc0bceeac49ade.tar.gz wix-2a87b3e728fb56202d21d402cecc0bceeac49ade.tar.bz2 wix-2a87b3e728fb56202d21d402cecc0bceeac49ade.zip | |
Generate the bundle's application manifest in the Burn backend.
Diffstat (limited to 'src')
3 files changed, 143 insertions, 16 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index a64bdcc1..8522eb3e 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | |||
| @@ -475,7 +475,7 @@ namespace WixToolset.Core.Burn | |||
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | { | 477 | { |
| 478 | var command = new CreateBundleExeCommand(this.Messaging, this.BackendHelper, this.IntermediateFolder, this.OutputPath, bundleSymbol, uxContainer, containers); | 478 | var command = new CreateBundleExeCommand(this.Messaging, this.BackendHelper, this.IntermediateFolder, this.OutputPath, bundleApplicationSymbol, bundleSymbol, uxContainer, containers); |
| 479 | command.Execute(); | 479 | command.Execute(); |
| 480 | 480 | ||
| 481 | fileTransfers.Add(command.Transfer); | 481 | fileTransfers.Add(command.Transfer); |
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs index 3cf6e0aa..f804a2d8 100644 --- a/src/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs | |||
| @@ -6,20 +6,24 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.IO; | 7 | using System.IO; |
| 8 | using System.Reflection; | 8 | using System.Reflection; |
| 9 | using System.Text; | ||
| 10 | using System.Xml; | ||
| 9 | using WixToolset.Data; | 11 | using WixToolset.Data; |
| 10 | using WixToolset.Data.Burn; | 12 | using WixToolset.Data.Burn; |
| 11 | using WixToolset.Data.Symbols; | 13 | using WixToolset.Data.Symbols; |
| 14 | using WixToolset.Dtf.Resources; | ||
| 12 | using WixToolset.Extensibility.Data; | 15 | using WixToolset.Extensibility.Data; |
| 13 | using WixToolset.Extensibility.Services; | 16 | using WixToolset.Extensibility.Services; |
| 14 | 17 | ||
| 15 | internal class CreateBundleExeCommand | 18 | internal class CreateBundleExeCommand |
| 16 | { | 19 | { |
| 17 | public CreateBundleExeCommand(IMessaging messaging, IBackendHelper backendHelper, string intermediateFolder, string outputPath, WixBundleSymbol bundleSymbol, WixBundleContainerSymbol uxContainer, IEnumerable<WixBundleContainerSymbol> containers) | 20 | public CreateBundleExeCommand(IMessaging messaging, IBackendHelper backendHelper, string intermediateFolder, string outputPath, WixBootstrapperApplicationSymbol bootstrapperApplicationSymbol, WixBundleSymbol bundleSymbol, WixBundleContainerSymbol uxContainer, IEnumerable<WixBundleContainerSymbol> containers) |
| 18 | { | 21 | { |
| 19 | this.Messaging = messaging; | 22 | this.Messaging = messaging; |
| 20 | this.BackendHelper = backendHelper; | 23 | this.BackendHelper = backendHelper; |
| 21 | this.IntermediateFolder = intermediateFolder; | 24 | this.IntermediateFolder = intermediateFolder; |
| 22 | this.OutputPath = outputPath; | 25 | this.OutputPath = outputPath; |
| 26 | this.BootstrapperApplicationSymbol = bootstrapperApplicationSymbol; | ||
| 23 | this.BundleSymbol = bundleSymbol; | 27 | this.BundleSymbol = bundleSymbol; |
| 24 | this.UXContainer = uxContainer; | 28 | this.UXContainer = uxContainer; |
| 25 | this.Containers = containers; | 29 | this.Containers = containers; |
| @@ -35,6 +39,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 35 | 39 | ||
| 36 | private string OutputPath { get; } | 40 | private string OutputPath { get; } |
| 37 | 41 | ||
| 42 | private WixBootstrapperApplicationSymbol BootstrapperApplicationSymbol { get; } | ||
| 43 | |||
| 38 | private WixBundleSymbol BundleSymbol { get; } | 44 | private WixBundleSymbol BundleSymbol { get; } |
| 39 | 45 | ||
| 40 | private WixBundleContainerSymbol UXContainer { get; } | 46 | private WixBundleContainerSymbol UXContainer { get; } |
| @@ -64,7 +70,11 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 64 | File.Copy(stubFile, bundleTempPath, true); | 70 | File.Copy(stubFile, bundleTempPath, true); |
| 65 | File.SetAttributes(bundleTempPath, FileAttributes.Normal); | 71 | File.SetAttributes(bundleTempPath, FileAttributes.Normal); |
| 66 | 72 | ||
| 67 | this.UpdateBurnResources(bundleTempPath, this.OutputPath, this.BundleSymbol); | 73 | var windowsAssemblyVersion = GetWindowsAssemblyVersion(this.BundleSymbol); |
| 74 | |||
| 75 | var applicationManifestData = GenerateApplicationManifest(this.BundleSymbol, this.BootstrapperApplicationSymbol, this.OutputPath, windowsAssemblyVersion); | ||
| 76 | |||
| 77 | UpdateBurnResources(bundleTempPath, this.OutputPath, this.BundleSymbol, windowsAssemblyVersion, applicationManifestData); | ||
| 68 | 78 | ||
| 69 | // Update the .wixburn section to point to at the UX and attached container(s) then attach the containers | 79 | // Update the .wixburn section to point to at the UX and attached container(s) then attach the containers |
| 70 | // if they should be attached. | 80 | // if they should be attached. |
| @@ -91,16 +101,105 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 91 | } | 101 | } |
| 92 | } | 102 | } |
| 93 | 103 | ||
| 94 | private void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo) | 104 | private static byte[] GenerateApplicationManifest(WixBundleSymbol bundleSymbol, WixBootstrapperApplicationSymbol bootstrapperApplicationSymbol, string outputPath, Version windowsAssemblyVersion) |
| 95 | { | 105 | { |
| 96 | var resources = new Dtf.Resources.ResourceCollection(); | 106 | const string asmv1Namespace = "urn:schemas-microsoft-com:asm.v1"; |
| 97 | var version = new Dtf.Resources.VersionResource("#1", 1033); | 107 | const string asmv3Namespace = "urn:schemas-microsoft-com:asm.v3"; |
| 108 | const string compatv1Namespace = "urn:schemas-microsoft-com:compatibility.v1"; | ||
| 109 | const string ws2005Namespace = "http://schemas.microsoft.com/SMI/2005/WindowsSettings"; | ||
| 110 | |||
| 111 | var bundleFileName = Path.GetFileName(outputPath); | ||
| 112 | var bundleAssemblyVersion = windowsAssemblyVersion.ToString(); | ||
| 113 | var bundlePlatform = bundleSymbol.Platform.ToString().ToLower(); | ||
| 114 | var bundleDescription = bundleSymbol.Name; | ||
| 115 | |||
| 116 | using (var memoryStream = new MemoryStream()) | ||
| 117 | using (var writer = new XmlTextWriter(memoryStream, Encoding.UTF8)) | ||
| 118 | { | ||
| 119 | writer.WriteStartDocument(); | ||
| 98 | 120 | ||
| 99 | version.Load(bundleTempPath); | 121 | writer.WriteStartElement("assembly", asmv1Namespace); |
| 100 | resources.Add(version); | 122 | writer.WriteAttributeString("manifestVersion", "1.0"); |
| 123 | |||
| 124 | writer.WriteStartElement("assemblyIdentity"); | ||
| 125 | writer.WriteAttributeString("name", bundleFileName); | ||
| 126 | writer.WriteAttributeString("version", bundleAssemblyVersion); | ||
| 127 | writer.WriteAttributeString("processorArchitecture", bundlePlatform); | ||
| 128 | writer.WriteAttributeString("type", "win32"); | ||
| 129 | writer.WriteEndElement(); // </assemblyIdentity> | ||
| 130 | |||
| 131 | if (!String.IsNullOrEmpty(bundleDescription)) | ||
| 132 | { | ||
| 133 | writer.WriteStartElement("description"); | ||
| 134 | writer.WriteString(bundleDescription); | ||
| 135 | writer.WriteEndElement(); | ||
| 136 | } | ||
| 137 | |||
| 138 | writer.WriteStartElement("dependency"); | ||
| 139 | writer.WriteStartElement("dependentAssembly"); | ||
| 140 | writer.WriteStartElement("assemblyIdentity"); | ||
| 141 | writer.WriteAttributeString("name", "Microsoft.Windows.Common-Controls"); | ||
| 142 | writer.WriteAttributeString("version", "6.0.0.0"); | ||
| 143 | writer.WriteAttributeString("processorArchitecture", bundlePlatform); | ||
| 144 | writer.WriteAttributeString("publicKeyToken", "6595b64144ccf1df"); | ||
| 145 | writer.WriteAttributeString("language", "*"); | ||
| 146 | writer.WriteAttributeString("type", "win32"); | ||
| 147 | writer.WriteEndElement(); // </assemblyIdentity> | ||
| 148 | writer.WriteEndElement(); // </dependentAssembly> | ||
| 149 | writer.WriteEndElement(); // </dependency> | ||
| 150 | |||
| 151 | writer.WriteStartElement("compatibility", compatv1Namespace); | ||
| 152 | writer.WriteStartElement("application"); | ||
| 153 | |||
| 154 | writer.WriteStartElement("supportedOS"); | ||
| 155 | writer.WriteAttributeString("Id", "{e2011457-1546-43c5-a5fe-008deee3d3f0}"); // Windows Vista | ||
| 156 | writer.WriteEndElement(); | ||
| 157 | writer.WriteStartElement("supportedOS"); | ||
| 158 | writer.WriteAttributeString("Id", "{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"); // Windows 7 | ||
| 159 | writer.WriteEndElement(); | ||
| 160 | writer.WriteStartElement("supportedOS"); | ||
| 161 | writer.WriteAttributeString("Id", "{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"); // Windows 8 | ||
| 162 | writer.WriteEndElement(); | ||
| 163 | writer.WriteStartElement("supportedOS"); | ||
| 164 | writer.WriteAttributeString("Id", "{1f676c76-80e1-4239-95bb-83d0f6d0da78}"); // Windows 8.1 | ||
| 165 | writer.WriteEndElement(); | ||
| 166 | writer.WriteStartElement("supportedOS"); | ||
| 167 | writer.WriteAttributeString("Id", "{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"); // Windows 10 | ||
| 168 | writer.WriteEndElement(); | ||
| 169 | |||
| 170 | writer.WriteEndElement(); // </application> | ||
| 171 | writer.WriteEndElement(); // </compatibility> | ||
| 172 | |||
| 173 | writer.WriteStartElement("trustInfo", asmv3Namespace); | ||
| 174 | writer.WriteStartElement("security"); | ||
| 175 | writer.WriteStartElement("requestedPrivileges"); | ||
| 176 | writer.WriteStartElement("requestedExecutionLevel"); | ||
| 177 | writer.WriteAttributeString("level", "asInvoker"); | ||
| 178 | writer.WriteAttributeString("uiAccess", "false"); | ||
| 179 | writer.WriteEndElement(); // </requestedExecutionLevel> | ||
| 180 | writer.WriteEndElement(); // </requestedPrivileges> | ||
| 181 | writer.WriteEndElement(); // </security> | ||
| 182 | writer.WriteEndElement(); // </trustInfo> | ||
| 183 | |||
| 184 | writer.WriteStartElement("application", asmv3Namespace); | ||
| 185 | writer.WriteStartElement("windowsSettings"); | ||
| 186 | writer.WriteStartElement("dpiAware", ws2005Namespace); | ||
| 187 | writer.WriteString("true"); | ||
| 188 | writer.WriteEndElement(); // </application> | ||
| 189 | writer.WriteEndElement(); // </windowSettings> | ||
| 190 | writer.WriteEndElement(); // </dpiAware> | ||
| 191 | |||
| 192 | writer.WriteEndDocument(); // </assembly> | ||
| 193 | writer.Close(); | ||
| 194 | |||
| 195 | return memoryStream.ToArray(); | ||
| 196 | } | ||
| 197 | } | ||
| 101 | 198 | ||
| 199 | private static Version GetWindowsAssemblyVersion(WixBundleSymbol bundleSymbol) | ||
| 200 | { | ||
| 102 | // Ensure the bundle info provides a full four part version. | 201 | // Ensure the bundle info provides a full four part version. |
| 103 | var fourPartVersion = new Version(bundleInfo.Version); | 202 | var fourPartVersion = new Version(bundleSymbol.Version); |
| 104 | var major = (fourPartVersion.Major < 0) ? 0 : fourPartVersion.Major; | 203 | var major = (fourPartVersion.Major < 0) ? 0 : fourPartVersion.Major; |
| 105 | var minor = (fourPartVersion.Minor < 0) ? 0 : fourPartVersion.Minor; | 204 | var minor = (fourPartVersion.Minor < 0) ? 0 : fourPartVersion.Minor; |
| 106 | var build = (fourPartVersion.Build < 0) ? 0 : fourPartVersion.Build; | 205 | var build = (fourPartVersion.Build < 0) ? 0 : fourPartVersion.Build; |
| @@ -108,14 +207,25 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 108 | 207 | ||
| 109 | if (UInt16.MaxValue < major || UInt16.MaxValue < minor || UInt16.MaxValue < build || UInt16.MaxValue < revision) | 208 | if (UInt16.MaxValue < major || UInt16.MaxValue < minor || UInt16.MaxValue < build || UInt16.MaxValue < revision) |
| 110 | { | 209 | { |
| 111 | throw new WixException(ErrorMessages.InvalidModuleOrBundleVersion(bundleInfo.SourceLineNumbers, "Bundle", bundleInfo.Version)); | 210 | throw new WixException(ErrorMessages.InvalidModuleOrBundleVersion(bundleSymbol.SourceLineNumbers, "Bundle", bundleSymbol.Version)); |
| 112 | } | 211 | } |
| 113 | 212 | ||
| 114 | fourPartVersion = new Version(major, minor, build, revision); | 213 | return new Version(major, minor, build, revision); |
| 115 | version.FileVersion = fourPartVersion; | 214 | } |
| 116 | version.ProductVersion = fourPartVersion; | 215 | |
| 216 | private static void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo, Version windowsAssemblyVersion, byte[] applicationManifestData) | ||
| 217 | { | ||
| 218 | const int burnLocale = 1033; | ||
| 219 | var resources = new Dtf.Resources.ResourceCollection(); | ||
| 220 | var version = new Dtf.Resources.VersionResource("#1", burnLocale); | ||
| 221 | |||
| 222 | version.Load(bundleTempPath); | ||
| 223 | resources.Add(version); | ||
| 224 | |||
| 225 | version.FileVersion = windowsAssemblyVersion; | ||
| 226 | version.ProductVersion = windowsAssemblyVersion; | ||
| 117 | 227 | ||
| 118 | var strings = version[1033] ?? version.Add(1033); | 228 | var strings = version[burnLocale] ?? version.Add(burnLocale); |
| 119 | strings["LegalCopyright"] = bundleInfo.Copyright; | 229 | strings["LegalCopyright"] = bundleInfo.Copyright; |
| 120 | strings["OriginalFilename"] = Path.GetFileName(outputPath); | 230 | strings["OriginalFilename"] = Path.GetFileName(outputPath); |
| 121 | strings["FileVersion"] = bundleInfo.Version; // string versions do not have to be four parts. | 231 | strings["FileVersion"] = bundleInfo.Version; // string versions do not have to be four parts. |
| @@ -138,7 +248,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 138 | 248 | ||
| 139 | if (!String.IsNullOrEmpty(bundleInfo.IconSourceFile)) | 249 | if (!String.IsNullOrEmpty(bundleInfo.IconSourceFile)) |
| 140 | { | 250 | { |
| 141 | var iconGroup = new Dtf.Resources.GroupIconResource("#1", 1033); | 251 | var iconGroup = new Dtf.Resources.GroupIconResource("#1", burnLocale); |
| 142 | iconGroup.ReadFromFile(bundleInfo.IconSourceFile); | 252 | iconGroup.ReadFromFile(bundleInfo.IconSourceFile); |
| 143 | resources.Add(iconGroup); | 253 | resources.Add(iconGroup); |
| 144 | 254 | ||
| @@ -150,11 +260,14 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 150 | 260 | ||
| 151 | if (!String.IsNullOrEmpty(bundleInfo.SplashScreenSourceFile)) | 261 | if (!String.IsNullOrEmpty(bundleInfo.SplashScreenSourceFile)) |
| 152 | { | 262 | { |
| 153 | var bitmap = new Dtf.Resources.BitmapResource("#1", 1033); | 263 | var bitmap = new Dtf.Resources.BitmapResource("#1", burnLocale); |
| 154 | bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile); | 264 | bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile); |
| 155 | resources.Add(bitmap); | 265 | resources.Add(bitmap); |
| 156 | } | 266 | } |
| 157 | 267 | ||
| 268 | var manifestResource = new Resource(ResourceType.Manifest, "#1", burnLocale, applicationManifestData); | ||
| 269 | resources.Add(manifestResource); | ||
| 270 | |||
| 158 | resources.Save(bundleTempPath); | 271 | resources.Save(bundleTempPath); |
| 159 | } | 272 | } |
| 160 | } | 273 | } |
diff --git a/src/test/WixToolsetTest.CoreIntegration/BundleFixture.cs b/src/test/WixToolsetTest.CoreIntegration/BundleFixture.cs index cf57eae1..9c5ec6ec 100644 --- a/src/test/WixToolsetTest.CoreIntegration/BundleFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/BundleFixture.cs | |||
| @@ -13,6 +13,7 @@ namespace WixToolsetTest.CoreIntegration | |||
| 13 | using WixToolset.Data; | 13 | using WixToolset.Data; |
| 14 | using WixToolset.Data.Burn; | 14 | using WixToolset.Data.Burn; |
| 15 | using WixToolset.Data.Symbols; | 15 | using WixToolset.Data.Symbols; |
| 16 | using WixToolset.Dtf.Resources; | ||
| 16 | using Xunit; | 17 | using Xunit; |
| 17 | 18 | ||
| 18 | public class BundleFixture | 19 | public class BundleFixture |
| @@ -115,6 +116,19 @@ namespace WixToolsetTest.CoreIntegration | |||
| 115 | "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' Publisher='Example Corporation' />" + | 116 | "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' Publisher='Example Corporation' />" + |
| 116 | "</Registration>", registrationElement.GetTestXml()); | 117 | "</Registration>", registrationElement.GetTestXml()); |
| 117 | } | 118 | } |
| 119 | |||
| 120 | var manifestResource = new Resource(ResourceType.Manifest, "#1", 1033); | ||
| 121 | manifestResource.Load(exePath); | ||
| 122 | var actualManifestData = Encoding.UTF8.GetString(manifestResource.Data); | ||
| 123 | Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + | ||
| 124 | "<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">" + | ||
| 125 | "<assemblyIdentity name=\"test.exe\" version=\"1.0.0.0\" processorArchitecture=\"x86\" type=\"win32\" />" + | ||
| 126 | "<description>~TestBundle</description>" + | ||
| 127 | "<dependency><dependentAssembly><assemblyIdentity name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" type=\"win32\" /></dependentAssembly></dependency>" + | ||
| 128 | "<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"><application><supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" /><supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" /><supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" /><supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" /><supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" /></application></compatibility>" + | ||
| 129 | "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\" /></requestedPrivileges></security></trustInfo>" + | ||
| 130 | "<application xmlns=\"urn:schemas-microsoft-com:asm.v3\"><windowsSettings><dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware></windowsSettings></application>" + | ||
| 131 | "</assembly>", actualManifestData); | ||
| 118 | } | 132 | } |
| 119 | } | 133 | } |
| 120 | 134 | ||
