inno-setupshortcut-filewindows-shortcut

Inno Setup desktop shortcut (link) which has "Run as administrator" advanced property set


I am struggling to get Inno setup (5.5.9u) to created a desktop shortcut that has an icon and has the advanced property of "Run as administrator" set.

Issue

This question, is a little different than: How to set 'Run as administrator' on a file using Inno Setup

Since what I am trying to do is not run a program at setup time with admin rights, (setup is already running at Admin), but rather leave a link on the desktop that has has the advanced property of "Run as Administrator".

Code Sample

[Icons]
Name: "{group}\EGPL Watson Uninstall"; Filename: "{uninstallexe}"; \
    WorkingDir: "{app}"
Name: "{commondesktop}\DashBoard"; \
    Filename: "{app}\dashboard\node_modules\electron\dist\electron.exe main.js"; \
    WorkingDir: "{app}\dashboard"; \
    IconFilename: "{src}\dashboard\build\configure.ico"

Solution

  • First, make sure you have a very good reason to run your application with Administrator privileges. User applications should not need Administrator privileges. If they need it, it's usually a sign of a bad design. One common (bad) reason to want an application to run with Administrator privileges, is that the application needs to write to its installation folder.

    See Application does not work when installed with Inno Setup


    Inno Setup does not natively support creating a shortcut with "Run as Administrator" flag set.

    The "Run as Administrator" flag is a bit in the .lnk file. See:

    You can set the bit using the following code:

    [Icons]
    Name: "{userdesktop}\My Program"; Filename: "{app}\MyProg.exe"; \
      AfterInstall: SetElevationBit('{userdesktop}\My Program.lnk')
    
    [Code]
    
    procedure SetElevationBit(Filename: string);
    var
      Buffer: string;
      Stream: TStream;
    begin
      Filename := ExpandConstant(Filename);
      Log('Setting elevation bit for ' + Filename);
    
      Stream := TFileStream.Create(FileName, fmOpenReadWrite);
      try
        Stream.Seek(21, soFromBeginning);
        SetLength(Buffer, 1);
        Stream.ReadBuffer(Buffer, 1);
        Buffer[1] := Chr(Ord(Buffer[1]) or $20);
        Stream.Seek(-1, soFromCurrent);
        Stream.WriteBuffer(Buffer, 1);
      finally
        Stream.Free;
      end;
    end;
    

    Tested on Unicode version of Inno Setup (the only version as of Inno Setup 6). But it should, even more naturally, work on Ansi version too.