I'm creating a shortcut on users Desktop with Inno Setup:
Name: "{commondesktop}\Setup"; Filename: "{app}\Setup.exe"; WorkingDir: "{pf}\Program"; IconFilename: "{app}\Setup.ico"
But users, with no admin rights, cannot delete this Shortcut, how to grant permissions to regular users, to delete this icon? Icon should be created on every user's desktop, but user should have permission to delete it.
As you know the application icon is built into the .exe file. The Inno Setup cannot modify the .exe files. And there's no other way to override the application icon by an external one. You have to edit the .exe file yourself, before building the installer.
The {commondesktop}
shortcut is shared on a common desktop. So there's only one copy of the shortcut.
If you allow the users to delete, when one user deletes the icon, it's deleted for every other user. That's why regular users are not allowed to modify/delete shared shortcuts.
While you can grant a delete permission to all users to that shortcut, this is not what you should do.
If each machine is used by one user only, install the icon to userdesktop
, not commondestop
. But that works only if that user (not Administrator) actually run the installer. For a general discussion about this problem, see Installing application for currently logged in user from Inno Setup installer running as Administrator.
There's no easy way to install the icons to all desktops. You have to use Pascal Scripting and iterate all profiles.
Easy way is to iterate subfolders of C:\Users
, creating a shortcut in Desktop
subfolder of each user's subfolder:
procedure CurStepChanged(CurStep: TSetupStep);
var
UsersPath: string;
CommonDesktopShortPath: string;
DesktopPath: string;
ShortcutPath: string;
FindRec: TFindRec;
ShortcutsCount: Integer;
begin
{ Once the files are installed }
if CurStep = ssPostInstall then
begin
Log('Creating shortcuts');
{ Assuming the common users root (typically C:\Users) is two level up }
{ from the current user desktop folder }
UsersPath :=
AddBackslash(ExtractFilePath(RemoveBackslash(ExtractFilePath(
RemoveBackslash(ExpandConstant('{userdesktop}'))))));
Log(Format('Users root [%s]', [UsersPath]));
CommonDesktopShortPath := GetShortName(ExpandConstant('{commondesktop}'));
Log(Format('Common desktop [%s]', [CommonDesktopShortPath]));
ShortcutsCount := 0;
{ Iterate all users }
if FindFirst(UsersPath + '*', FindRec) then
begin
try
repeat
{ Just directories, not interested in files }
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
begin
{ Check if there is a Desktop subfolder }
DesktopPath := UsersPath + FindRec.Name + '\Desktop';
if DirExists(DesktopPath) then
begin
if CompareText(
CommonDesktopShortPath, GetShortName(DesktopPath)) = 0 then
begin
Log(Format('Skipping common desktop [%s]', [DesktopPath]));
end
else
begin
ShortcutPath := DesktopPath + '\My Program.lnk';
Log(Format(
'Found desktop folder for user [%s], creating shortcut [%s]', [
FindRec.Name, ShortcutPath]));
try
ShortcutPath := CreateShellLink(
ShortcutPath, 'My Program', ExpandConstant('{app}\MyProg.exe'), '',
ExpandConstant('{app}'), '', 0, SW_SHOWNORMAL);
Log(Format('Shortcut [%s] created', [ShortcutPath]));
Inc(ShortcutsCount);
except
Log(Format('Failed to create shortcut: %s', [GetExceptionMessage]));
end;
end;
end;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
Log(Format('%d shortcuts created', [ShortcutsCount]));
end
else
begin
Log(Format('Error listing [%s]', [UsersPath]));
end;
end;
end;
The code will work only, if the desktops are local and in common locations.
If you need a more robust solution, you can iterate profiles listed in
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
Or use a WMI query like:
SELECT * FROM Win32_UserAccount WHERE localAccount = true and disabled = false
See Query list of Windows accounts in Inno Setup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With