Inno Setup Создание индивидуальных ярлыков на всех рабочих столах всех пользователей

Я создаю ярлык на рабочем столе пользователей с Inno Setup:

Name: "{commondesktop}\Setup"; Filename: "{app}\Setup.exe"; WorkingDir: "{pf}\Program"; IconFilename: "{app}\Setup.ico"

Но пользователи, не имеющие прав администратора, не могут удалить этот ярлык, как предоставить разрешения обычным пользователям, чтобы удалить этот значок? Значок должен быть создан на рабочем столе каждого пользователя, но у пользователя должно быть разрешение на его удаление.

1 ответ

Решение

{commondesktop} ярлык доступен на общем рабочем столе. Так что есть только одна копия ярлыка.

Если вы разрешите пользователям удалять, когда один пользователь удаляет значок, он удаляется для всех остальных пользователей. Вот почему обычные пользователи не могут изменять / удалять общие ярлыки.

Хотя вы можете предоставить всем пользователям ярлык на удаление, это не то, что вам следует делать.


Если каждый компьютер используется только одним пользователем, установите значок userdesktopне commondestop, Но это работает, только если этот пользователь (а не администратор) действительно запускает установщик. Общее обсуждение этой проблемы см. В разделе " Установка приложения для текущего пользователя, вошедшего в систему, из программы установки Inno Setup, работающей от имени администратора".

Нет простого способа установить иконки на все рабочие столы. Вы должны использовать Pascal Scripting и повторять все профили.

Простой способ состоит в том, чтобы перебрать подпапки C:\Users, создав ярлык в Desktop подпапка каждой подпапки пользователя:

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;

Код будет работать только в том случае, если рабочие столы локальные и в общих местах.

Если вам нужно более надежное решение, вы можете выполнить итерации профилей, перечисленных в

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

Или используйте запрос WMI, например:

SELECT * FROM Win32_UserAccount WHERE localAccount = true and disabled = false
Другие вопросы по тегам