Creating a Non-Admin Installer with Inno Setup

Posted August 4th, 2008 by kyle

Most Windows applications require admin rights for installation, which explains why most users run as admin. It also explains why software viruses and spyware are so rampant and why Microsoft invented User Account Control in Windows Vista. Note that even applications that require admin rights for installation should run properly for non-admin (and non-elevated Vista) users.

Sometimes, it does make sense to allow an application to be installed without requiring administrative privileges (which we do for Ultra Recall). Some would argue this is just a way to subvert the IT police, but it doesn’t sidestep any security restrictions or permissions that the non-admin user already has, and sometimes the IT police are more like Nazis anyway.

Inno Setup is a popular tool for creating program installers, and it is fairly simple to create a non-privileged installer with this tool.

The first thing to do is add

PrivilegesRequired=none

to the [Setup] section of the installation script. This will cause Windows to run the install program without elevation for non-admin users.

Second, don’t install any files to {pf}, {win}, {sys}, or other system paths. DLL dependencies can be installed to the installation path.

Third, the installer should detect whether it is running as an elevated admin user and default the installation path under Program Files if it is or a user-writeable path if not. This can be done by using a DefaultDirName in the [Setup] section like this:

DefaultDirName={code:DefDirRoot}\AppName

and a [Code] section like this:

[Code]
function IsRegularUser(): Boolean;
begin
Result := not (IsAdminLoggedOn or IsPowerUserLoggedOn);
end;

function DefDirRoot(Param: String): String;
begin
if IsRegularUser then
Result := ExpandConstant('{localappdata}')
else
Result := ExpandConstant('{pf}')
end;

Fourth, any [Registry] entries written under HKLM will fail if the installer is run by a non-admin/elevated user and should be marked to ignore failure by adding the noerror flag. And if possible and appropriate, add the equivalent HKCU registry entries, which will work on a non-admin installation.

Finally, non-admin users do not have permissions to register COM DLLs and OCXs. One option, which is not recommended, is to also register in user-level registry locations. A better option where possible is to utilize Registry-Free COM.

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • BlinkList
  • blogmarks
  • del.icio.us
  • digg
  • feedmelinks
  • Furl
  • LinkaGoGo
  • NewsVine
  • Reddit
  • Simpy
  • Spurl
  • YahooMyWeb

14 Comments on “Creating a Non-Admin Installer with Inno Setup”

  1. Andy Brice Says:

    Just what I was looking for. Thanks!

    BTW does it matter that admin users will end up with the same entry in HKLM and HKCU?

  2. kyle Says:

    No.

  3. Slobodan Ivkovic Says:

    I’ve been struggling with UAC using Inno Setup for some time now.

    Problem that bathers me is that when installing software as admin user, desktop, startup and programs icons are created for admin account used for UAC elevation (if he defers from non privileged user that started installation). Only solution that I’m using, forced, is to create icons for “all users” (using AlwaysUsePersonalGroup=no – which is default).

    Any help for my problem?

  4. kyle Says:

    You could create a secondary IS installer to create icons, etc. and run it from the main script (with the runasoriginaluser flag).
    http://www.jrsoftware.org/ishelp/topic_runsection.htm

  5. Tom Dukes Says:

    Thanks alot, this helped us out of a big hole.

  6. Alen Says:

    Thank you!
    This is exactly what I needed.

  7. craig Says:

    I’m doing what you are doing. Here is my problem though: what if admin user doesn’t want it applied to all users and just wants it installed for himself? Do you have any advice on that can that be handled?

  8. kyle Says:

    The secondary installer option with runasoriginaluser (see 4th comment) could be used for that (as long the the admin user doesn’t explicitly run the installer elevated — see notes in IS help link above).

  9. craig Says:

    I think what you are saying is something like give user a radiobutton to pick for all users or current users and then launch the correct installer based on the choice.

    What will happen when user installs an update. Won’t he get that choice again? If you think my assumption is correct, do you know of a way to determine if there was already a prior install to skip that dialog? (Or maybe I have it all wrong. I’m pretty new at this.)

  10. kyle Says:

    Maybe provide two installers, one with PrivilegesRequired=admin (for admin users who want to install for all users), and another with PrivilegesRequired=none (for users who can/want to install only for themselves).

  11. craig Says:

    I think that is what it may come down to. I wish there was an easy inno function that returned a value if app was already installed.

    I did have a solution worked up with radio buttons and based on that I set the textbox in the location page, but if it had already been installed to a custom loction, it was overwriting that location and causing problems. I need an easy way to know if already installed, and where.

    Thanks much.

  12. Oleg Says:

    Does localappdata exist on Windows XP? What is the next step if anybody want to install on XP?

  13. kyle Says:

    Yes, it exists on Windows XP.

  14. Carlos Ramirez Says:

    Hello,

    Excellent post. I implemented it simply copying and pasting your post, and it works like a charm. The only thing is that I used {userpf} probably it didn’t exist in InnoSetup when you wrote the post

    Regards,
    Carlos

Comment: