{"id":266,"date":"2011-04-07T19:20:15","date_gmt":"2011-04-07T19:20:15","guid":{"rendered":"http:\/\/www.calvert.ch\/geodesix\/?page_id=266"},"modified":"2011-04-08T12:26:20","modified_gmt":"2011-04-08T12:26:20","slug":"creating-the-setup-project","status":"publish","type":"page","link":"https:\/\/www.calvert.ch\/geodesix\/help\/source-code\/creating-the-setup-project\/","title":{"rendered":"Creating the Setup project"},"content":{"rendered":"<p>In <a href=\"http:\/\/www.calvert.ch\/geodesix\/help\/source-code\/vsto\/\">Avoiding VSTO<\/a>, I lauded AddinExpress for having such an easy interface to create a Steup Project. I stand by what I said, but GeodesiX goes a fair bit further than just implementing a few Excel UDFs. The problem that I had to address is:<\/p>\n<blockquote><p>Excel UDF descriptions are <strong>per-user<\/strong> and <strong>not <\/strong>for all users of the PC. Technically, they are stored the in registry in HKCU and not HKLM. This means that you <strong>have to<\/strong> install your UDFs for each login separately. This is a pain in the arse.<\/p><\/blockquote>\n<p>You might naively think that it is sufficient to create the appropriate entries in HKCU during the Setup. A good idea, but it won&#8217;t work because:<\/p>\n<ul>\n<li>If you create a per-user Setup, you&#8217;ll have to run the complete Setup for every user who needs your UDF.<\/li>\n<li>If you create an All-Users Setup, it runs with elevated privilege. This privilege is acquired by changing the user of the Setup task to &#8220;System&#8221;. If the Setup task modifies HKCU, it will modify the HKCU <strong>of the user &#8220;System&#8221;<\/strong> and <strong>not<\/strong> the HKCU of the user running the Setup.<br \/>\nIn other words, if you login as System, you&#8217;ll be able to use the UDF, as any other user you won&#8217;t.<\/li>\n<\/ul>\n<p>Note that &#8216;professional&#8217; setup programs like InstallShield suffer from the same problem (and don&#8217;t offer a solution). The only solution that I have found to this is to use the undocumented Active Setup (take a look at the nice description <a href=\"http:\/\/www.sepago.de\/helge\/2010\/04\/22\/active-setup-explained\/\" target=\"_new\">Active Setup explained<\/a>\u00a0on Helge Klein&#8217;s blog).<\/p>\n<p>The swindle is performed like this:.<\/p>\n<ol>\n<li>At the end of the Setup, we create a custom action which runs the command-line program PostInstall.Postinstall.Main #31#. It calls PostInstall.SetupUDF.SetupUDF #32#.<\/li>\n<li>SetupUDF creates the registry entries to invoke Active Install at the next login (for any users of the machine).<\/li>\n<li>Whenever a user logs on in future, Active Setup checks to see the currents user&#8217;s registry keys at HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Active Setup\\Installed&nbsp;Components to see if they are the same as HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Active Setup\\Installed&nbsp;Components. If they differ, Active Setup invokes the program stored in the StubPath key: Our UDFInstaller #33#.<\/li>\n<li>UDFInstaller creates the registry keys in HKCU that define the UDF and we&#8217;re done.<\/li>\n<\/ol>\n<p>The one thing to watch out for (both in PostInstall and UDFInstaller) is that we&#8217;re running as a 32-bit task. Making naive registry changes using My.Computer.Registry will work on 32-bit operating systems, but fail on 64bit systems because when a 32bit task modifies the registry on a 64bit system, the modifications are made under the Wow6432Node key.<\/p>\n<p>When a 64bit Excel starts, it accesses the real registry key and won&#8217;t find the USD entries. You can read all the gory details <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa384232(v=vs.85).aspx\" target=\"_new\">here<\/a>.<\/p>\n<p><del datetime=\"2011-04-08T12:23:15+00:00\">There is a downside to this: when the Setup has completed, the UDFs won&#8217;t be installed until the user logs out and logins in again (we show him a message asking him to do this). The final step of Setup, in PostInstall #42#, is to display the help Excel file, but the UDFs aren&#8217;t installed, so the Geodesic formulas would return #NAME#. They don&#8217;t because ReadMe.xls has <strong>calculation set to manual<\/strong>. Clever users will notice this if they try to add or modify the help file whilst they&#8217;re reading it. This is a despicable trick, but what the eye doesn&#8217;t see, the heart doesn&#8217;t bleed over.<\/del> Fixed 6 April 2011.<\/p>\n<p>A final Setup note: I build GeodesiX on a 64bit machine, so the references to Addin Express point to &#8220;Program Files (x86)&#8221;:<\/p>\n<p><a href=\"http:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/setupproperties.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-326\" title=\"setupproperties\" src=\"http:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/setupproperties.jpg\" alt=\"\" width=\"762\" height=\"513\" srcset=\"https:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/setupproperties.jpg 762w, https:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/setupproperties-300x201.jpg 300w\" sizes=\"auto, (max-width: 762px) 100vw, 762px\" \/><\/a><\/p>\n<p>If you&#8217;re running a 32bit machine, you&#8217;ll need to adjust this here and in the Setup Custom Actions:<\/p>\n<p><a href=\"http:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/customactions.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-327\" title=\"customactions\" src=\"http:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/customactions.jpg\" alt=\"\" width=\"995\" height=\"234\" srcset=\"https:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/customactions.jpg 995w, https:\/\/www.calvert.ch\/geodesix\/files\/2011\/04\/customactions-300x70.jpg 300w\" sizes=\"auto, (max-width: 995px) 100vw, 995px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Avoiding VSTO, I lauded AddinExpress for having such an easy interface to create a Steup Project. I stand by what I said, but GeodesiX goes a fair bit further than just implementing a few Excel UDFs. The problem that <a href='https:\/\/www.calvert.ch\/geodesix\/help\/source-code\/creating-the-setup-project\/' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":247,"menu_order":9,"comment_status":"open","ping_status":"closed","template":"momoframepage.php","meta":{"footnotes":""},"class_list":["post-266","page","type-page","status-publish","hentry","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/pages\/266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/comments?post=266"}],"version-history":[{"count":9,"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/pages\/266\/revisions"}],"predecessor-version":[{"id":333,"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/pages\/266\/revisions\/333"}],"up":[{"embeddable":true,"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/pages\/247"}],"wp:attachment":[{"href":"https:\/\/www.calvert.ch\/geodesix\/wp-json\/wp\/v2\/media?parent=266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}