views:

364

answers:

3

I have a Win32 application that includes an EXE, an ActiveX control (DLL) and a COM server (EXE) and I am using Inno Setup 5 to build my installer. Many of our customers use limited user accounts where the user has no admin rights and because the COM components require to be registered (which writes to HKEY_CLASSES_ROOT), my setup file must run with elevated (admin) privileges. I think this in unavoidable (sadly, I can't use registration-free COM because of the EXE COM server I have). However, I would like to create an update installer that can be ran as a limited user and am looking for some advice.

What I am thinking is the following:

  • The initial setup (first time installation) installs the application into %ALLUSERSPROFILE%\Application Data\CompanyName\AppName instead of %PROGRAMFILES%. The COM components are registered as normal (as they won't already exist).
  • Subsequent updates (using a different Inno Setup script) will simply copy the new files into %ALLUSERSPROFILE%\Application Data\CompanyName\AppName. Hopefully even a limited user will have write access to this folder and as the COM components have already been registered, admin access won't be required.

This would mean that my customers could upgrade to the latest and greatest version without the hassle of using an Administrator account. Is this acceptable or is this likely to bite me on the backside? I'm pretty sure Google Chrome does something similar but as it has no COM components (as far as I can tell) even the initial setup can be as a limited user.

Any advice from others who have faced this issue would be very welcome indeed.

A: 

If you dumped inno-setup and used MSIs - MSI files support the idea of limited user installation of patches. An administrator must authorize the initial install, thereafter, digital signatures in patch msi files are processed by the elevated msi service without requiring user elevation.

You can duplicate this basic idea yourself - during an initial administrative install, install a service component that has the necessary access. When processing patches, ask the service process to process the EXE COM server registrations.

Chris Becke
+1  A: 

I don't know for sure, but I seem to recall COM servers support per-user installation, and maybe that goes for EXE servers as well.

If so, change your registration code to write information to HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT.

The COM infrastructure should do the lookup first per-user and then per-machine.

It's worth an experiment anyway.

Kim Gräsman
I think you might be onto something...
Rob
+1  A: 

OK, I found a way to create a limited-user installation script with both my COM server and COM objects being registered per-user.

I am using the latest version of ATL (v9) that ships with MSVC 2008 to create my COM server and COM objects. Turns out that you can register the COM server per-user via the new /RegServerPerUser switch. I tested this with limited user accounts on XP, Vista and Windows 7 and it works perfectly.

Next, the COM controls. Again, ATL9 to the rescue. You can register a control per-user by ensuring that RegSvr32 calls your control's DllInstall function, passing it a command-line parameter of user. So, to register a control in this way you simply do:

regsvr32.exe /i:user /n MyControl.DLL

Again, I tested this on XP, Vista and Windows 7 and it works fine.

I then made the following changes to my Inno Setup script:

  • The default installation folder will be {pf} (i.e. C:\Program Files) if the user has Admin rights. If not, then it defaults to {commonappdata} (i.e. C:\Documents and Settings\All Users).
  • Register my COM server using the new /RegServerPerUser switch.
  • I removed the regserver flags from my COM objects and instead added support to call regsvr32 using the new 'user' switch.

All of these changes are easy to do using the Inno Setup {code} feature.

Thanks to Kim for setting me down the per-user COM install path.

Rob
Thanks for the extensive follow-up.
Kim Gräsman