Inno Setup Create individual shortcuts on all desktops of all users

孤街醉人 提交于 2019-11-29 11:22:30

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!