Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inno Setup Create individual shortcuts on all desktops of all users

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.

like image 226
Artur Tychina Avatar asked Feb 05 '16 12:02

Artur Tychina


People also ask

How do I change the icon on my Inno?

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.


1 Answers

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.

like image 159
Martin Prikryl Avatar answered Oct 13 '22 09:10

Martin Prikryl