{"id":163,"date":"2010-03-17T14:57:10","date_gmt":"2010-03-17T19:57:10","guid":{"rendered":"http:\/\/blog.bitsofgenius.com\/?p=163"},"modified":"2010-12-05T00:58:06","modified_gmt":"2010-12-05T04:58:06","slug":"getting-the-custom-installation-portion-of-a-visual-studio-setup-project-to-well-work","status":"publish","type":"post","link":"https:\/\/blog.bitsofgenius.com\/?p=163","title":{"rendered":"Getting the custom installation portion of a Visual Studio setup project to &#8230; well, work!"},"content":{"rendered":"<p>I was creating a Visual Studio solution with a Setup project, and needed to add a set of custom installation steps to the setup.  The process for this (Custom Actions) is easy to find in Microsoft&#8217;s online documentation, and in many forums.<\/p>\n<p>Yet one thing is common: the level of failure and frustration expressed in the forums is widespread.  A lot of folks had problems getting the custom class to work.. and so did I.  My initial test for the custom install was just to create a log file persisting the &#8220;savedState&#8221; contents to a file on the root of C:, so I could examine its contents.  The custom installation section never ran.<\/p>\n<p>No matter what I did, something was missing.  A few people on the forums strongly advocated abandoning the custom installation, and just go to a batch file with scripts.  I wasn&#8217;t ready to go down that path.  I just sensed that something simple was missing.<\/p>\n<p>The answer for this comes from my colleague, <a href=\"http:\/\/www.blogger.com\/profile\/15222762755454099175\" target=\"_blank\">Patrick Thompson<\/a>, who answered a seemingly off the wall question while we chatted in the hallway outside of the office.  He evidently spent a lot of hours figuring this out sometime ago, and saved me a lot of grief.  And it is simple&#8230;<\/p>\n<p>I was able to create my Class library for the custom installation, and include it in the application folder in the setup project.  In the custom actions panel, I added the custom project to the Install and Rollback folders: the two methods my code was overriding with custom code.<\/p>\n<p><img decoding=\"async\" src=\"\/images\/CustomInstall1.png\" alt=\"The original configuration\" \/><\/p>\n<p>The code for the class is <a href=\"\/CodeView\/MyInstall_cs.html\" target=\"_blank\">here<\/a>.  Note that the class does not use a namespace, so that it resides in the default namespace.<\/p>\n<p>But, in order for the custom code to actually work properly&#8230; <em><strong>All of the folders (methods) in the custom action panel must be populated with the same assembly, even if the assembly isn&#8217;t doing any real overrides to the base method<\/strong><\/em>.  So, the proper way this should be setup is&#8230;<\/p>\n<p><img decoding=\"async\" src=\"\/images\/CustomInstall3.png\" alt=\"The proper configuration\" \/><\/p>\n<p>Sure enough after making the change, the next compile and execution of the MSI package generated my test file on the C: drive, just as it should have.  So there you have the missing piece to custom actions, when it looks like all hope is lost.<\/p>\n<p>And here is the output written to the log file, in case you wonder what savedState settings are available by default:<\/p>\n<pre lang=\"text\">\r\n\r\nInstall...\r\n_reserved_nestedSavedStates = \"System.Collections.IDictionary[]\"\r\n_reserved_lastInstallerAttempted = \"-1\"\r\nCommitted (Context.Parameters...\r\naction = \"commit\"\r\ninstalltype = \"notransaction\"\r\nassemblypath = \"C:\\Program Files\\Bits of Genius\\Folder Manifest\\FolderManifestCustomInstallation.dll\"\r\nlogfile = \"\"\r\n\r\n<\/pre>\n<p><em>FolderManifest is a utility application tied to Windows Explorer context, which I will be posting shortly.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was creating a Visual Studio solution with a Setup project, and needed to add a set of custom installation steps to the setup. The process for this (Custom Actions) is easy to find in Microsoft&#8217;s online documentation, and in many forums. Yet one thing is common: the level of failure and frustration expressed in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,16,17],"tags":[],"class_list":["post-163","post","type-post","status-publish","format-standard","hentry","category-dotnetclasslibraries","category-dotnettechniques","category-tips-and-tricks"],"_links":{"self":[{"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/posts\/163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=163"}],"version-history":[{"count":20,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/posts\/163\/revisions"}],"predecessor-version":[{"id":285,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=\/wp\/v2\/posts\/163\/revisions\/285"}],"wp:attachment":[{"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bitsofgenius.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}