{"id":1553,"date":"2007-04-20T22:06:16","date_gmt":"2007-04-20T22:06:16","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/heaths\/2007\/04\/20\/custom-action-guidelines\/"},"modified":"2019-02-17T15:30:19","modified_gmt":"2019-02-17T22:30:19","slug":"custom-action-guidelines","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/custom-action-guidelines\/","title":{"rendered":"Custom Action Guidelines"},"content":{"rendered":"<p>Rob Mensching, father of Windows Installer XML (WiX), blogs about why <a href=\"http:\/\/robmensching.com\/blog\/archive\/2007\/04\/19\/Managed-Code-CustomActions-no-support-on-the-way-and-heres.aspx\">managed custom actions are a bad idea<\/a>. Aaron Stebner <a href=\"http:\/\/blogs.msdn.com\/astebner\/archive\/2007\/04\/20\/link-to-more-details-about-the-dangers-of-managed-code-custom-actions-in-an-msi.aspx\">follows up<\/a> by saying (and has <a href=\"http:\/\/blogs.msdn.com\/astebner\/archive\/2005\/03\/10\/392280.aspx\">said before<\/a>):<\/p>\n<ol>\n<li>&#8220;Avoid custom actions entirely if at all possible.\n<\/li>\n<li>&#8220;Investigate the WiX build-in custom actions if you find a setup action that is not natively supported in Windows Installer.\n<\/li>\n<li>&#8220;If you have to write custom action code, do not use managed code when doing so.&#8221;\n<\/li>\n<\/ol>\n<p>How do you know what&#8217;s natively supported? Those who know me already know what I&#8217;m going to say: <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa372022.aspx\">read the docs<\/a>. The <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa372866.aspx\">Windows Installer SDK<\/a> has some information if you look for it, and you certainly should because setup and servicing cannot be taken for granted. Windows Installer is complex, but a powerful transactional installer. To help disseminate some of this information since it can be sparse, there are a number of good blogs to read about rules, experiences, and guidelines:\n<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/astebner\">http:\/\/blogs.msdn.com\/astebner<\/a>\n\t\t<\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/heaths\">http:\/\/blogs.msdn.com\/heaths<\/a>\n\t\t<\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/rflaming\/\">http:\/\/blogs.msdn.com\/rflaming\/<\/a>\n\t\t<\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/windows_installer_team\">http:\/\/blogs.msdn.com\/windows_installer_team<\/a>\n\t\t<\/li>\n<li><a href=\"http:\/\/msmvps.com\/blogs\/installsite\">http:\/\/msmvps.com\/blogs\/installsite<\/a>\n\t\t<\/li>\n<li><a href=\"http:\/\/robmensching.com\/blog\">http:\/\/robmensching.com\/blog<\/a>\n\t\t<\/li>\n<\/ul>\n<p>There are other things you should do when writing custom actions, and I am working with people throughout the company to define guidelines. In general, besides what Aaron and Rob are saying &ndash; along with <a href=\"http:\/\/blogs.msdn.com\/robmen\/archive\/2004\/05\/20\/136530.aspx\">not using script custom actions<\/a> &ndash; you should consider the following:\n<\/p>\n<ul>\n<li>Schedule machine-changing custom actions as deferred custom actions. Especially with <a href=\"http:\/\/blogs.msdn.com\/rflaming\/archive\/tags\/UAC+in+MSI\/default.aspx\">UAC<\/a>, this is very important to support rollback and many other scenarios.\n<\/li>\n<li>Developer data-driven custom actions. This makes it easier to service (i.e., patch) resources since you can transform a table and don&#8217;t have to reship a custom action. This is especially important to support patch uninstall, since anything a patch added won&#8217;t exist when the patch is uninstall and its <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/09\/12\/464047.aspx\">transform removed from the view<\/a>.\n<\/li>\n<li>In most cases, relate your resources to components in your custom tables and schedule deferred actions based on both the state and the action of each resource&#8217;s component. You will find many good examples of this in the <a href=\"http:\/\/sourceforge.net\/projects\/wix\">WiX sources<\/a> available on SourceForge.\n<\/li>\n<li>Avoid using broadly scoped properties like <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa370576.aspx\">PATCH<\/a> or <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa371175.aspx\">REINSTALL<\/a>. This can prevent scenarios like slipstream installs where the product and patch are installed together in a single transaction.\n<\/li>\n<li>Limit dependencies for custom actions. If you install such dependencies, this limits when your custom actions can be scheduled since your custom action &ndash; and installation &ndash; will fail without the dependency installed. This is especially important when linking to CRT8 and newer that install as side-by-side native assemblies, and aren&#8217;t available on Vista until after the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa367991.aspx\">commit<\/a> phase is complete.\n<\/li>\n<\/ul>\n<p>Log. I&#8217;ll say it again: log. The Windows Installer engine is quite stable and well secured, so the closest thing available to a crash dump is a verbose log. When run on Windows Installer 3.0 and newer, you can also turn on debug logging. You can use the system <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa369776.aspx\">Logging<\/a> policy to set &#8220;voicewarmupx&#8221; (easy to remember), along with the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa368263.aspx\">Debug<\/a> policy for extra information such as the ever-handy sequence dump which shows you all the information generated to sequence patches. You can also specify logging on the <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa367988.aspx\">command line<\/a> or bootstrap developers can call <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa370091.aspx\">MsiEnableLog()<\/a>. There are a lot of great <a href=\"http:\/\/blogs.technet.com\/richard_macdonald\/archive\/2007\/04\/02\/How-to-Interpret-Windows-Installer-Logs.aspx\">posts<\/a> about <a href=\"http:\/\/blogs.msdn.com\/astebner\/archive\/2005\/08\/01\/446328.aspx\">parsing<\/a> and <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/12\/14\/503796.aspx\">understanding<\/a> Windows Installer logs.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rob Mensching, father of Windows Installer XML (WiX), blogs about why managed custom actions are a bad idea. Aaron Stebner follows up by saying (and has said before): &#8220;Avoid custom actions entirely if at all possible. &#8220;Investigate the WiX build-in custom actions if you find a setup action that is not natively supported in Windows [&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":[10,14,17,20,23,41],"class_list":["post-1553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-custom-actions","tag-development","tag-essentials","tag-installation","tag-logging","tag-uac"],"acf":[],"blog_post_summary":"<p>Rob Mensching, father of Windows Installer XML (WiX), blogs about why managed custom actions are a bad idea. Aaron Stebner follows up by saying (and has said before): &#8220;Avoid custom actions entirely if at all possible. &#8220;Investigate the WiX build-in custom actions if you find a setup action that is not natively supported in Windows [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1553","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=1553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1553\/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=1553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=1553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=1553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}