{"id":1193,"date":"2008-01-15T03:42:51","date_gmt":"2008-01-15T03:42:51","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/heaths\/2008\/01\/15\/different-packages-are-required-for-different-processor-architectures\/"},"modified":"2019-02-17T15:30:06","modified_gmt":"2019-02-17T22:30:06","slug":"different-packages-are-required-for-different-processor-architectures","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/different-packages-are-required-for-different-processor-architectures\/","title":{"rendered":"Different Packages are Required for Different Processor Architectures"},"content":{"rendered":"<p>A common question is how to create a Windows Installer package that installs 32-bit binaries on 32-bit platforms, and both 32- and 64-bit binaries on 64-bit platforms. If you&#8217;re actually trying to install 64-bit binaries to appropriate directories and write to the 64-bit view of the registry, the short answer is that you can&#8217;t build a single package.<\/p>\n<p>Before delving into the details, let me clarify that both 32- and 64-bit binaries can be installed to either <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa370881.aspx\">ProgramFilesFolder<\/a> or <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa370880.aspx\">ProgramFiles64Folder<\/a>, but may not load correctly into a 64- or 32-bit process, respectively. The Windows Installer SDK, for example, installs all of x86, IA64, and x64 binaries under ProgramFilesFolder for link time support.<\/p>\n<p>But when you need to install files correctly, multiple packages are required because not all 64-bit features are lit up if the package isn&#8217;t marked as a 64-bit package. That is, the Template summary property must distinctly list Intel for x86, Intel64 for IA64, and x64 for x64 platforms (AMD64 is supported for backward compatibility). The <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa372070(VS.85).aspx\">Template summary property documentation<\/a> clearly states that only a single platform can be specified.<\/p>\n<blockquote>\n<p>A Windows Installer package cannot be marked as supporting both Intel64 and x64; for example, the Template Summary property value of Intel64,x64 is invalid.<\/p>\n<p>A Windows Installer package cannot be marked as supporting both 32-bit and 64-bit platforms; for example, Template Summary property values such as Intel,x64 or Intel,Intel64 are invalid.<\/p>\n<\/blockquote>\n<p>Attempting to install a 64-bit package on a 32-bit platform results in <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa368542.aspx\">Windows error 1633<\/a>. Assuming no other errors, installing a 32-bit package on a 64-bit platform appears to work but components may not actually be installed correctly. Files in components to be installed under ProgramFiles64Folder, for example, wind up in ProgramFilesFolder.<\/p>\n<p>If we examine a log from a 32-bit package with 64-bit components defined that is installed on an x64 platform, we can see that directories like ProgramFiles64Folder are initially defined correctly but are redirected back to the 32-bit equivalent directory.<\/p>\n<p><code>MSI (s) (B4:20) [16:59:17:976]: WIN64DUALFOLDERS: 'C:Program Files (x86)' will substitute 17 characters in 'C:Program Files' folder path. (mask argument = 0, the folder pair's iSwapAttrib member = 0).<br \/>MSI (s) (B4:20) [16:59:17:976]: PROPERTY CHANGE: Modifying ProgramFiles64Folder property. Its current value is 'C:Program Files'. Its new value: 'C:Program Files (x86)'.<\/code><\/p>\n<p>But when writing registry values, you can see by the <span class=\"highlight\" style=\"background: yellow\">BinaryType<\/span> parameter that Windows Installer knows the difference and Windows Installer will write to the correct 32- or 64-bit view of the registry. You can confirm this using a tool like <em>regedit.exe<\/em>.<\/p>\n<p><code>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegOpenKey(Root=-2147483646,Key=SoftwareHeath StewartExample,,<span class=\"highlight\" style=\"background: yellow\">BinaryType=0<\/span>)<br \/>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegAddValue(,Value=32-bit Example,)<br \/>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegAddValue(Name=Example,Value=32-bit Registry Example,)<br \/>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegOpenKey(Root=-2147483646,Key=SoftwareHeath StewartExample,,<span class=\"highlight\" style=\"background: yellow\">BinaryType=1<\/span>)<br \/>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegAddValue(,Value=64-bit Example,)<br \/>MSI (s) (B4:20) [16:59:18:445]: Executing op: RegAddValue(Name=Example,Value=64-bit Registry Example,)<\/code><\/p>\n<p>You can&#8217;t simply condition components using standard properties like <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa372497.aspx\">VersionNT64<\/a>. Even when installing a package marked as Intel on a 64-bit machine, properties like VersionNT64, <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa370522.aspx\">Msix64<\/a>, and <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa369553.aspx\">Intel64<\/a> are still defined.<\/p>\n<p>Essentially, most features are lit-up depending on the machine type except for where files are installed. Even 64-bit custom actions will run in a 64-bit custom action server despite how the package is attributed as shown in the log snippet below. For binary custom actions, the bitness of the binary will dictate whether a 32- or 64-bit custom action server is created. For script custom actions, the custom action must be attributed with msidbCustomActionType64BitScript (0x1000); of course, you <a href=\"http:\/\/blogs.msdn.com\/robmen\/archive\/2004\/05\/20\/136530.aspx\">shouldn&#8217;t use script custom actions<\/a> anyway.<\/p>\n<p><code>MSI (s) (74:14) [11:04:43:203]: Executing op: CustomActionSchedule(Action=CA_OutputString32,ActionType=1025,Source=BinaryData,Target=OutputString,)<br \/>MSI (s) (74:14) [11:04:43:203]: Creating MSIHANDLE (1) of type 790536 for thread 3604<br \/>MSI (s) (74:44) [11:04:43:203]: Invoking remote custom action. DLL: C:WINDOWSInstallerMSI243.tmp, Entrypoint: OutputString<br \/>MSI (s) (74:2C) [11:04:43:203]: Generating random cookie.<br \/>MSI (s) (74:2C) [11:04:43:219]: Created Custom Action Server with PID 2260 (0x8D4).<br \/>MSI (s) (74:64) [11:04:43:250]: Running as a service.<br \/>MSI (s) (74:64) [11:04:43:250]: Hello, I'm your <span class=\"highlight1\" style=\"background: lime\">32bit Impersonated custom action server<\/span>.<\/p>\n<p>MSI (s) (74:14) [11:04:43:250]: Executing op: CustomActionSchedule(Action=CA_OutputString64,ActionType=1025,Source=BinaryData,Target=OutputString,)<br \/>MSI (s) (74:14) [11:04:43:250]: Creating MSIHANDLE (3) of type 790536 for thread 3604<br \/>MSI (s) (74:8C) [11:04:43:266]: Invoking remote custom action. DLL: C:WINDOWSInstallerMSI244.tmp, Entrypoint: OutputString<br \/>MSI (s) (74:2C) [11:04:43:266]: Generating random cookie.<br \/>MSI (s) (74:2C) [11:04:43:266]: Created Custom Action Server with PID 3480 (0xD98).<br \/>MSI (s) (74:08) [11:04:43:282]: Running as a service.<br \/>MSI (s) (74:64) [11:04:43:282]: Hello, I'm your <span class=\"highlight1\" style=\"background: lime\">64bit Impersonated custom action server<\/span>.<\/code><\/p>\n<p>This is predicated on whether or not you&#8217;re invoking embedded binaries or installed binaries. Since your installed binaries in a 32-bit package will install to the 32-bit location even on a 64-bit machine, whichever file was installed last &#8211; taking into account <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa368267.aspx\">default file versioning<\/a> &#8211; would dictate the bitness of the custom action server.<\/p>\n<p>If the goal is to decrease the payload, you can still create separate packages but define your media entries so that 32- and 64-bit payloads (each of IA64 and x64 if you&#8217;ll be installing either) are in separate cabinets. Read more about <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2006\/05\/19\/602133.aspx\">file sequences and media entries<\/a>. You can then put all the <em>.msi<\/em> packages in the same directory and put all of the cabinets in that directory as well. This is actually how the <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2007\/12\/18\/fixes-in-microsoft-net-framework-2-0-sp1-and-3-0-sp1.aspx\">.NET Framework 2.0 SP1 and 3.0 SP1<\/a> packages are laid out. Cabinets can be shared between packages for common files, rather than having distinct sets for each supported platform.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A common question is how to create a Windows Installer package that installs 32-bit binaries on 32-bit platforms, and both 32- and 64-bit binaries on 64-bit platforms. If you&#8217;re actually trying to install 64-bit binaries to appropriate directories and write to the 64-bit view of the registry, the short answer is that you can&#8217;t build [&hellip;]<\/p>\n","protected":false},"author":389,"featured_media":3843,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[4,10,20,23],"class_list":["post-1193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-64-bit","tag-custom-actions","tag-installation","tag-logging"],"acf":[],"blog_post_summary":"<p>A common question is how to create a Windows Installer package that installs 32-bit binaries on 32-bit platforms, and both 32- and 64-bit binaries on 64-bit platforms. If you&#8217;re actually trying to install 64-bit binaries to appropriate directories and write to the 64-bit view of the registry, the short answer is that you can&#8217;t build [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/users\/389"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/comments?post=1193"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1193\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media\/3843"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media?parent=1193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=1193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=1193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}