{"id":2483,"date":"2006-02-01T14:48:00","date_gmt":"2006-02-01T14:48:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/heaths\/2006\/02\/01\/64-bit-managed-custom-actions-with-visual-studio\/"},"modified":"2006-02-01T14:48:00","modified_gmt":"2006-02-01T14:48:00","slug":"64-bit-managed-custom-actions-with-visual-studio","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/64-bit-managed-custom-actions-with-visual-studio\/","title":{"rendered":"64-bit Managed Custom Actions with Visual Studio"},"content":{"rendered":"<p>A reader who happened across my post on\n<a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/10\/24\/484266.aspx\">Windows\nInstaller on 64-bit Platforms<\/a>\n<a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/10\/24\/484266.aspx#521415\">\nmentioned<\/a> a problem with running 64-bit managed custom actions using the\nVisual Studio 2005 Windows Installer project. This also recently cropped up in\nan internal discussion alias.<\/p>\n<p>The issue is that if you build a managed class library project targeting a 64-bit platform\nusing <code>\/platform:x64<\/code> or <code>\/platform:Itanium<\/code> and install a\nWindows Installer package built in Visual Studio 2005 on a\n64-bit machine a\n<a href=\"http:\/\/msdn2.microsoft.com\/library\/System.BadImageFormatException\"><code>System.BadImageFormatException<\/code><\/a> is thrown. The reason is because\nthe native shim packaged with the <i>.msi<\/i> file is a 32-bit executable.<\/p>\n<p>Let&#8217;s step back a minute, though, to how to build a Windows Installer setup\nproject with managed custom actions. I won&#8217;t go into\n<a href=\"http:\/\/support.microsoft.com\/default.aspx?scid=kb;EN-US;816169\">details<\/a>, but basically you\ncreate a new Class Library project that contains one or more derivatives from\nthe\n<a href=\"http:\/\/msdn2.microsoft.com\/library\/System.Configuration.Install.Installer\">\n<code>System.Configuration.Install.Installer<\/code> class<\/a>. In the Custom\nActions editor for your Windows Installer project you can right-click on a\nspecific phase (Install, Commit, Rollback, or Uninstall) or, preferably, the root node\n(which adds the custom action to all phases with the appropriate custom action\ntypes) and add whatever you want from\nproject output to a specific file in your file system. If your class library is\nin the same solution I recommend clicking &#8220;Add Output&#8221; in the custom action\neditor dialog.<\/p>\n<p>You should also click on the Windows Installer project and change the\nTargetPlatform property to either x64 or Itanium, depending on what you&#8217;re\ntargeting. This makes sure that 64-bit components are installed to the 64-bit\nfolders like [ProgramFiles64Folder]. If you don&#8217;t set this according to what\nbinaries you&#8217;re installing (which can be a mix of both 32- and 64-bit) 64-bit\nfiles will be installed into [ProgramFilesFolder] which, on 64-bit platforms,\nis, for example, <i>C:Program Files (x86)<\/i>.<\/p>\n<p>Back to the problem. When you build the Windows Installer project in Visual\nStudio 2005 it embeds the 32-bit version of <i>InstallUtilLib.dll<\/i> into the\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/binary_table.asp\">\nBinary table<\/a> as InstallUtil. When Windows Installer executes your managed\ncustom action it actually is calling the <code>ManagedInstall<\/code> entry point function\nfrom <i>InstallUtilLib.dll<\/i> as a\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/custom_action_type_1.asp\">type 1<\/a> deferred custom action (1025) which creates\nan instance of the CCW\n<a href=\"http:\/\/msdn2.microsoft.com\/library\/System.Configuration.Install.IManagedInstaller\"> <code>System.Configuration.Install.IManagedInstaller<\/code> interface<\/a>\nand runs your <code>Installer<\/code> classes. Since the native <i>\nInstallUtilLib.dll<\/i> is 32-bit it loads the 32-bit Framework which will throw\nthe <code>BadImageFormatException<\/code> since your managed class library is 64-bit.<\/p>\n<p>To workaround this issue you either need to import the appropriate bitness of\n<i>InstallUtilLib.dll<\/i> into the Binary table for the InstallUtil record or &#8211;\nif you do have or will have 32-bit managed custom actions add it as a new record\nin the Binary table and adjust the\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/customaction_table.asp\">\nCustomAction table<\/a> to use the 64-bit Binary table record for 64-bit managed\ncustom actions.<\/p>\n<p>To replace the 32-bit <i>InstallUtilLib.dll<\/i> with the 64-bit bitness,<\/p>\n<\/p>\n<ol>\n<li>Open the resulting <i>.msi<\/i> in Orca from the Windows Installer SDK<\/li>\n<li>Select the Binary table<\/li>\n<li>Double click the cell [Binary Data] for the record InstallUtil<\/li>\n<li>Make sure &#8220;Read binary from filename&#8221; is selected and click the Browse\n\tbutton<\/li>\n<li>Browse to <i>%WINDIR%Microsoft.NETFramework64v2.0.50727<\/i><\/li>\n<li>Select <i>InstallUtilLib.dll<\/i><\/li>\n<li>Click the Open button<\/li>\n<li>Click the OK button<\/li>\n<\/ol>\n<p><i>Note that the Framework64 directory is only installed on 64-bit platforms and\nthat it corresponds to the 64-bit processor type. That is, you won&#8217;t find the\nx64 flavor of InstallUtilLib.dll on an IA64 machine.<\/i><\/p>\n<p>If you already have or anticipate having 32-bit custom actions in future\npatches &#8211; and I recommend this approach because the future is difficult to\npredict &#8211; you should add a new record.<\/p>\n<\/p>\n<ol>\n<li>Open the resulting <i>.msi<\/i> in Orca from the Windows Installer SDK<\/li>\n<li>Select the Binary table<\/li>\n<li>Click the Tables menu and then Add Row<\/li>\n<li>Enter, for example, InstallUtil64 for the Name<\/li>\n<li>Select the Data row and click the Browse button<\/li>\n<li>Browse to <i>%WINDIR%Microsoft.NETFramework64v2.0.50727<\/i><\/li>\n<li>Select <i>InstallUtilLib.dll<\/i><\/li>\n<li>Click the Open button<\/li>\n<li>Click the OK button<\/li>\n<li>Select the CustomAction table<\/li>\n<li>For each custom action where the Source column is InstallUtil and only those\ncustom actions that are 64-bit managed custom actions (or that were built with <code>\/platform:anycpu<\/code>,\nthe default, where you want to run as 64-bit custom actions), change the value\nto, for example, InstallUtil64<\/li>\n<\/ol>\n<p>This only affects DLLs build with <code>\/target:library<\/code>. Managed EXEs will run\ncorrectly according to what platform they target.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A reader who happened across my post on Windows Installer on 64-bit Platforms mentioned a problem with running 64-bit managed custom actions using the Visual Studio 2005 Windows Installer project. This also recently cropped up in an internal discussion alias. The issue is that if you build a managed class library project targeting a 64-bit [&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,14,20],"class_list":["post-2483","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-64-bit","tag-development","tag-installation"],"acf":[],"blog_post_summary":"<p>A reader who happened across my post on Windows Installer on 64-bit Platforms mentioned a problem with running 64-bit managed custom actions using the Visual Studio 2005 Windows Installer project. This also recently cropped up in an internal discussion alias. The issue is that if you build a managed class library project targeting a 64-bit [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/2483","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=2483"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/2483\/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=2483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=2483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=2483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}