Installer confusion - per user/all users

Add-in Express™ Support Service
That's what is more important than anything else

Installer confusion - per user/all users
 
Nick Whymark




Posts: 14
Joined: 2018-01-15
Hi,

This is regarding an Outlook Addin, using Add-in Express version 9.3.4641. I am revisiting an installer I wrote a few years ago which successfully installs for all users. I'm using a 3rd party installer (advanced installer) and I wanted to change the package to run either "per user" or for "all users".

I think I understand what I need to do to make it one or the other, but I'm really confused by all the places I need to change and what the relationship between them is. I'd really like to have a detailed understanding of the following and what they actually do (technically):

- RegisterForAllUsers = true (or false) in the addin module
- privileges="user" (or "administrator") in the loaderSettings in adxloader.dll.manifest
- The /privileges=user (or "admin") switch on adxregistrator.exe in the custom actions of the installer.


I also have a couple of specific questions:

1. I have noticed from the log that adxregistrator decides whether to write to the HKLM/HKCU based on the privileges value in the adxloader.dll.manifest.Is the /privileges switch overridden by this, if not what does it do? It's also confusing because of the file names "adxloader" vs "adxregistrator" - you would expect adxregistrator to use its own manifest. What is the adxloader manifest, do I even need one if I have the /privileges switch?
2. What does RegisterForAllUsers in the addin module do? Is that used by the add-in, adxloader or adxregistrator? Why do we need it, what does it do?
3. The big question is how do I change these values in an installer based on the installation type? The adxregistrator switch is easy but the other two seem much harder particularly the one in the code (addin module).
4. Lastly, what is adxpatch. Is that relevent to my situation (a 3rd party installer tool), or does it only apply if the installer is built using your tools? What does it actually do, what files does it change if any?

I'm sure there are technical reasons for all of this, but I think it is very confusing to have to change it in so many places. Couldn't there just be a single config file or something?

Thank you in advance,
Nick.
Posted 07 Jan, 2021 08:03:17 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
Hello Nick,

adxloader.dll.manifest is a way to supply the loader (and registrar) with information about your add-in. I also suggest that you check section Registration-time privileges at https://www.add-in-express.com/docs/net-deploying-addins.php.

Note that setting the RegisterForAllUsers property changes the privileges attribute on the manifest. That means, at the deployment time, you can simply change the manifest and ignore setting the RegisterForAllUsers property. I assume this property is a remnant of an old deployment concept; the property was re-used to let the user change the manifest. Not a best solution, I admit.

adxpatch is required if you create a Visual Studio Installer based setup project. I assume all the aspects that this utility controls are available in an Advanced Installer setup project. Moreover, adxpatch hides the For Me and For Everyone controls which you need to be shown. I would recommend that you create a WiX based setup project and choose the "Generate dual-purpose setup project" check box on the last step. This creates a setup project that lets the user choose whether to install the add-in per-user or per-machine. I recommend that you study it and reproduce the same logic in your installer.

In the sample project I created, I see the following parameters passed to adxregistrator on different setup stages:

    <!-- The "adxregistrator.exe" custom action. -->
    <CustomAction Id="_3E6C9C82_BCB0_474A_BC5D_5D4C1C6E62F4" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand="/install=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perMachine&quot;" Impersonate="no" />
    <CustomAction Id="_CFB71E04_8AF3_4B14_B329_6BE6CEB19A80" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand="/install=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perUser&quot;" Impersonate="yes" />
    <!-- The "adxregistrator.exe" custom action. -->
    <CustomAction Id="_AECECE9E_E718_4C76_85FC_6CDDB86F3B69" BinaryKey="adxregistrator_exe" Execute="rollback" ExeCommand="/uninstall=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perMachine&quot; /generateLogFile=false" Impersonate="no" />
    <CustomAction Id="_2E90B333_F9AB_4113_8A42_D3536876DF8D" BinaryKey="adxregistrator_exe" Execute="rollback" ExeCommand="/uninstall=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perUser&quot; /generateLogFile=false" Impersonate="yes" />
    <!-- The "adxregistrator.exe" custom action. -->
    <CustomAction Id="_396178B7_224E_4BA3_B83A_21A09440D4FE" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand="/uninstall=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perMachine&quot;" Impersonate="no" />
    <CustomAction Id="_70B5F2C1_E22B_4ED4_B949_CAE695E9AF3E" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand="/uninstall=&quot;[TARGETDIR]$(var.MyAddin1.TargetFileName)&quot; /scope=&quot;perUser&quot;" Impersonate="yes" />


Although it is complex we haven't recognized the need to change this, yet. I suppose this is because such a task doesn't occur really often. When I have a convenient moment I'll raise this question.


Andrei Smolin
Add-in Express Team Leader
Posted 08 Jan, 2021 03:40:36 Top
Nick Whymark




Posts: 14
Joined: 2018-01-15
Hi Andrei,

Thanks for coming back, I hope you and everyone there are keeping well in these tricky times! Your reply was very helpful.

Just to begin by saying I have no problem with advanced installer and creating the actual installer package (MSI/EXE), it's the add-in express bits I was having trouble with.

So, I believe you are saying:

1. I can ignore the RegisterForAllUsers property in the add module (source code) as long as I deploy an adxloader manifest with the correct "privileges" setting. I think this was a crucial bit I was missing!
2. adxregistrator does the registration of both the add-in (office reg keys) and the COM component (more reg keys):
a) The location of the add-in keys is controlled by the value of privileges in the adxloader manifest.
b) The location of the COM keys is controlled by the /privileges switch of adxregistrator.

Does this sound correct?

Can I confirm that you are saying the adxloader needs to know whether the add-in is installed per user or for all users AT RUNTIME, and that it uses the value in the manifest to determine this?

And finally in an unrelated question can you tell me what the configFileName in the loaderSettings of the adxloader manifest does? I only ask because I have it set to configFileName="App.config" but I don't deploy an App.config file so I wasn't sure if could just take it out?


Many thanks again,
Nick.
Posted 08 Jan, 2021 06:04:02 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
Hello Nick,

1. Correct. When you register the add-in, the value of the privileges attribute (from the manifest) is used instead of the RegisterForAllUsers property.
2. Correct. We give the recommended combinations of these values in section Registration-time privileges at https://www.add-in-express.com/docs/net-deploying-addins.php.

On your questions.

The loader doesn't use the privileges attribute.

You can ignore this for now. A .Config file is used when Add-in Express creates a folder-based AppDomain. We describe this in section https://www.add-in-express.com/docs/net-office-tips.php#configuring-add-in.


Andrei Smolin
Add-in Express Team Leader
Posted 11 Jan, 2021 08:02:24 Top
Nick Whymark




Posts: 14
Joined: 2018-01-15
Thanks Andrei, got it all working although I seem to have broken something else now, hey ho! :)
Posted 15 Jan, 2021 14:19:18 Top