Updating shortcut (.lnk) files to require elevation

124 views
Skip to first unread message

Bill Stewart

unread,
Jun 28, 2024, 2:29:49 PM (7 days ago) Jun 28
to innosetup
For those interested, please test:


This tool uses the technique described in Raymond Chen's blog posting:

How do I mark a shortcut file as requiring elevation?[1]

Caveats:

1. Are you really sure your program needs to run as administrator (elevated)? Unless your program performs an administrative function (such as changing system settings), you need to evaluate whether you really should be running it elevated in the first place.

2. For a program that really does need to run elevated (for example, it really does change a system setting), you should use a manifest that tells Windows that it must run elevated.

If you have read and understood these caveats but have no other choice, you can use this tool to set the "Run as administrator" option for a shortcut (.lnk) file.

Gavin Lambert

unread,
Jun 30, 2024, 10:16:37 PM (5 days ago) Jun 30
to innosetup
On Saturday, June 29, 2024 at 6:29:49 AM UTC+12 Bill Stewart wrote:
If you have read and understood these caveats but have no other choice, you can use this tool to set the "Run as administrator" option for a shortcut (.lnk) file.

As a software developer, you never have no other choice -- i.e. it is absolutely never the correct choice to set this flag.  Your choices include (roughly in decreasing order of correctness):

1. Rewrite your application such that it does not require admin privileges at all.
2. Rewrite your application such that it does not require admin privileges at startup, but can elevate on demand in the hopefully small number of cases that truly do require admin permissions.  (There are a few variations on how to do this, with differing requirements and security implications.)
3. Add a manifest to your application (ideally as a resource, but it can be a loose file if you can't rebuild your app at all) to require admin permissions at startup.
4. Write a thin launcher app with such a manifest and launch your app from this instead (as sub-processes will remain elevated by default).

Most often, requiring admin permissions only occurs because the application is not behaving correctly in the first place.

The shortcut flag exists only for end-users, who lack the ability to do any of the above things, and is a workaround for broken software.  Don't release broken software.

Bill Stewart

unread,
Jul 1, 2024, 9:28:35 AM (4 days ago) Jul 1
to innosetup
On Sunday, June 30, 2024 at 8:16:37 PM UTC-6 Gavin Lambert wrote:

As a software developer, you never have no other choice -- i.e. it is absolutely never the correct choice to set this flag.  Your choices include (roughly in decreasing order of correctness):

1. Rewrite your application such that it does not require admin privileges at all.
2. Rewrite your application such that it does not require admin privileges at startup, but can elevate on demand in the hopefully small number of cases that truly do require admin permissions.  (There are a few variations on how to do this, with differing requirements and security implications.)
3. Add a manifest to your application (ideally as a resource, but it can be a loose file if you can't rebuild your app at all) to require admin permissions at startup.
4. Write a thin launcher app with such a manifest and launch your app from this instead (as sub-processes will remain elevated by default).

Most often, requiring admin permissions only occurs because the application is not behaving correctly in the first place.

The shortcut flag exists only for end-users, who lack the ability to do any of the above things, and is a workaround for broken software.  Don't release broken software.

Of course, I agree in general (which is why I posted a link to Raymond Chen's blog posting). However, despite these caveats, there may still be use cases where doing any of the above is not possible or impractical. IMO it's better to use the binary interfaces (IPersistFile, IShellLinkDataList, etc.) than directly modifying bits in the .lnk file. Hence the utility.
Message has been deleted

Luís César Zanetti

unread,
Jul 1, 2024, 3:59:33 PM (4 days ago) Jul 1
to inno...@googlegroups.com
[Setup]
AppName=My App
AppVersion=1.0
DefaultDirName={commonpf}\My App
OutputDir=.

[Files]
Source: compiler:Examples\MyProg.exe; DestDir: {app};

[Icons]
Name: "{userdesktop}\My Program"; Filename: "{app}\MyProg.exe"; \
  AfterInstall: SetElevationBit('{userdesktop}\My Program.lnk')


[Code]

procedure SetElevationBit(Filename: string);
var
  Buffer: Ansistring;
  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;


Em seg., 1 de jul. de 2024 às 14:57, Pinky Poit <pinkyg...@gmail.com> escreveu:
Anyway, it's nice that the installer has the ability to set this checkbox of a shortcut.

понедельник, 1 июля 2024 г. в 05:16:37 UTC+3, Gavin Lambert:

--
You received this message because you are subscribed to the Google Groups "innosetup" group.
To unsubscribe from this group and stop receiving emails from it, send an email to innosetup+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/innosetup/5292cbf9-9962-46ba-9485-9182d1386ebbn%40googlegroups.com.

Gavin Lambert

unread,
Jul 1, 2024, 7:53:59 PM (4 days ago) Jul 1
to innosetup
On Tuesday, July 2, 2024 at 1:28:35 AM UTC+12 Bill Stewart wrote:
Of course, I agree in general (which is why I posted a link to Raymond Chen's blog posting). However, despite these caveats, there may still be use cases where doing any of the above is not possible or impractical. IMO it's better to use the binary interfaces (IPersistFile, IShellLinkDataList, etc.) than directly modifying bits in the .lnk file. Hence the utility.

I agree that using the API as you're doing is vastly superior to hacking the file as the SetElevationBit function just posted here does.  But still, absolutely never do either of these things (but SetElevationBit is vastly worse).

Raymond's blog post very clearly says to not do this either.  I disagree that there are any cases where doing one of the things that I stated are impossible or impractical -- anyone who can't do those things has no business distributing software in the first place.

The shortcut setting is for user use only.  Either to work around broken software or as a user preference to skip some optional elevation inside the app -- but the app needs to be written correctly to handle optional elevation in the first case for that to be useful.  There are absolutely no circumstances that the developer should distribute software with this flag set, because there are always better options.

Bill Stewart

unread,
Jul 2, 2024, 9:54:28 AM (3 days ago) Jul 2
to innosetup
On Monday, July 1, 2024 at 5:53:59 PM UTC-6 Gavin Lambert wrote:

I agree that using the API as you're doing is vastly superior to hacking the file as the SetElevationBit function just posted here does.  But still, absolutely never do either of these things (but SetElevationBit is vastly worse).

Raymond's blog post very clearly says to not do this either.  I disagree that there are any cases where doing one of the things that I stated are impossible or impractical -- anyone who can't do those things has no business distributing software in the first place.

The shortcut setting is for user use only.  Either to work around broken software or as a user preference to skip some optional elevation inside the app -- but the app needs to be written correctly to handle optional elevation in the first case for that to be useful.  There are absolutely no circumstances that the developer should distribute software with this flag set, because there are always better options.
 
As far as "anyone who can't do those things has no business distributing software"--aside from this possibly sounding a bit elitist, I would say that in order to implement this tool in an Inno Setup installer one needs a fair understanding of how to call an external executable. Such a person can read and understand the implications of using the tool and why it's not the best solution for most cases, as already stated here (and also in the tool's documentation).

Also, you may not have considered that this tool might have applicability in other use cases besides installers. For example, system administrators might be interested in using this tool to set the SLDF_RUNAS_USER bit for a shortcut that gets distributed by a GPO (for example, a PowerShell shortcut that gets distributed to administrator user profiles).

Bill

Gavin Lambert

unread,
Jul 2, 2024, 7:56:26 PM (3 days ago) Jul 2
to innosetup
On Wednesday, July 3, 2024 at 1:54:28 AM UTC+12 Bill Stewart wrote:
As far as "anyone who can't do those things has no business distributing software"--aside from this possibly sounding a bit elitist, I would say that in order to implement this tool in an Inno Setup installer one needs a fair understanding of how to call an external executable. Such a person can read and understand the implications of using the tool and why it's not the best solution for most cases, as already stated here (and also in the tool's documentation).

Installers are modifying someone else's computer using admin permissions.  It's absolutely necessary to be very careful what you're doing and to use that power responsibly.  I don't see that as elitist, I see that as necessary to understand your responsibility to be doing the right things and avoid doing the wrong things.  Claiming that an app requires admin permissions when it actually doesn't (the developer just didn't design the application correctly) is one of those wrong things.

This isn't unique to Windows either -- apps written for Linux or other platforms also need to be designed properly for the OS's permissions model -- it's just that it's historically been easier to get away with assuming everyone has admin permissions within easy reach on Windows, whereas in the open-source world it's more likely to be treated as a bug (and the installers are often created by multiple separate teams of people who know the rules better).
 
Also, you may not have considered that this tool might have applicability in other use cases besides installers. For example, system administrators might be interested in using this tool to set the SLDF_RUNAS_USER bit for a shortcut that gets distributed by a GPO (for example, a PowerShell shortcut that gets distributed to administrator user profiles).
 
I'm not saying that there are no situations where your tool may be useful.  I'm saying that your tool (or the other methods) should never be used as part of a software installer, because there are always better options.  Even if the executable in question cannot be modified (though that should be rare).

So I'm not trying to pick on your tool specifically, it's just that there's been a sudden influx of threads asking how to do something in Inno that absolutely shouldn't be done, and "here's a tool to help you do that better" is not a good response to that.  The correct response to "how do I shoot people in the foot?" is not "here's a gun", even if the gun in question has better safety features than the one they were already using.

Bill Stewart

unread,
Jul 3, 2024, 9:59:13 AM (2 days ago) Jul 3
to innosetup
On Tuesday, July 2, 2024 at 5:56:26 PM UTC-6 Gavin Lambert wrote:

Installers are modifying someone else's computer using admin permissions.

That's not always the case, of course, as per-user installers are relatively common.

In any case, the tool is available, despite the fact that it might get used incorrectly. (This tool is certainly not unique in that regard.)

Bill

Gavin Lambert

unread,
Jul 3, 2024, 8:20:57 PM (2 days ago) Jul 3
to innosetup
On Thursday, July 4, 2024 at 1:59:13 AM UTC+12 Bill Stewart wrote:
On Tuesday, July 2, 2024 at 5:56:26 PM UTC-6 Gavin Lambert wrote:

Installers are modifying someone else's computer using admin permissions.

That's not always the case, of course, as per-user installers are relatively common.

They exist, certainly; I'm less sure about "relatively common", since IT likes installers requiring admin permissions so that they can block the majority of installations by not granting them, or at the very least can train people to be suspicious of UAC prompts when they're not deliberately installing something.

But the need for responsibility still exists even for per-user installers, as it's still code running on someone else's PC.  And it would be even more bizarre if a per-user installer wants to install an admin-only shortcut.

Bill Stewart

unread,
Jul 4, 2024, 3:56:09 PM (yesterday) Jul 4
to innosetup
On Wednesday, July 3, 2024 at 6:20:57 PM UTC-6 Gavin Lambert wrote:

And it would be even more bizarre if a per-user installer wants to install an admin-only shortcut.

You might be surprised. Suppose someone wanted to write a per-user installer that, as part of its process, creates a PowerShell shortcut that prompts for elevation and that said installer only gets executed for administrator profiles. One of the most straightforward ways of meeting this requirement is simply to create the shortcut and set the elevation bit. (Yes, there are other potential ways of solving this problem, but that would be beside the point.)

Gavin Lambert

unread,
Jul 4, 2024, 8:16:41 PM (yesterday) Jul 4
to innosetup
On Friday, July 5, 2024 at 7:56:09 AM UTC+12 Bill Stewart wrote:
You might be surprised. Suppose someone wanted to write a per-user installer that, as part of its process, creates a PowerShell shortcut that prompts for elevation and that said installer only gets executed for administrator profiles. One of the most straightforward ways of meeting this requirement is simply to create the shortcut and set the elevation bit. (Yes, there are other potential ways of solving this problem, but that would be beside the point.)

But then it wouldn't work if the user ran the script directly instead of via the special shortcut.  And it's not hard to write a self-elevating script, which is roughly equivalent to putting an admin manifest on an executable (and thus the better option).  It's even almost the same code as just detecting whether you have admin perms, which the script ought to be doing up-front regardless to avoid getting into situations where it does a bunch of other work before crashing out and leaving the user in a broken state. 

Bill Stewart

unread,
10:09 AM (11 hours ago) 10:09 AM
to innosetup
On Thursday, July 4, 2024 at 6:16:41 PM UTC-6 Gavin Lambert wrote:

But then it wouldn't work if the user ran the script directly instead of via the special shortcut.  And it's not hard to write a self-elevating script, which is roughly equivalent to putting an admin manifest on an executable (and thus the better option).  It's even almost the same code as just detecting whether you have admin perms, which the script ought to be doing up-front regardless to avoid getting into situations where it does a bunch of other work before crashing out and leaving the user in a broken state. 

I wasn't referring to running a PowerShell script but rather a shortcut to powershell.exe itself. And I already noted that yes, there are other potential ways of meeting this requirement. I'm simply pointing out a potential legitimate use case of setting SLDF_RUNAS_USER in a .lnk file. We already agree that most of the time people are doing this for the wrong reasons. I am saying that there are potential legitimate use cases for it that maybe you haven't considered, and this tool can help with those. If you disagree with that position, that's fine; we'll agree to disagree there.
Reply all
Reply to author
Forward
0 new messages