Inno Setup - Доступ к непривилегированным папкам учетной записи из установщика, который требует привилегий

Я использую Inno Setup для установки документов / файлов, а не приложения, и это в первую очередь для пользователей Windows 7. Как таковой мой DestDir основывается на {userdocs} так что все файлы будут установлены в папке ниже библиотеки документов этого пользователя.

Проблема возникает, когда я использую тот же установщик для установки шрифта TTF. Это требует повышенных привилегий (admin или же superuser). Проблема, с которой я сталкиваюсь, заключается в том, что, если пользователь, не являющийся администратором, запускает установку, он корректно запрашивает через UAC пароль администратора / суперпользователя... но в этот момент DestDir для установки вносит изменения в папку документов администратора, а не в папку документов пользователя. Есть ли способ обойти это или предотвратить это?

Пример, учетная запись без прав администратора Fre имеет путь документов:

C:\Users\Fred\My Documents\

И если я не включу шрифт TTF как часть установки, это то, что установщик будет использовать в качестве базового пути для установки {userdocs} и это работает отлично.

Если я включу шрифт TTF как часть установки с тем же пользователем Fred, не являющимся администратором, к тому времени, когда установка будет завершена {userdocs} стал

C:\Users\AdminUser\My Documents\ 

... что не является желаемым результатом... просто необходимы права администратора для установки шрифта и файлы должны быть установлены в области документов реального пользователя.

Благодарю.

1 ответ

Решение

Создайте дочерний установщик для шрифтов с PrivilegesRequired=admin директива, что вы будете запускать из основного установщика без повышенных прав.

Основной код установщика будет выглядеть так:

[Setup]
PrivilegesRequired=lowest

[Files]
Source: "ttfsetup.exe"; DestDir: {tmp}; Flags: deleteafterinstall

[Run]
Filename: "{tmp}\ttfsetup.exe"; Parameters: /silent; StatusMsg: "Installing TTF fonts..."

И, конечно же, вы должны удалить дочерний установщик из главного деинсталлятора.

Вы также можете убедиться, что пользователь не запустил главный установщик явно с правами администратора. См. Мой ответ на Как написать в каталог Мои документы пользователя с помощью установщика, когда пользователь использовал "Запуск от имени администратора".

Другой способ реализовать это - использовать ShellExec функция с runas глагол для запуска утилиты внешнего копирования с повышенными правами (copy, xcopy, robocopy). Смотрите Inno Setup - Зарегистрируйте компоненты как администратор (он работает regsvr32, но концепция та же).


Другим вариантом является выполнение процесса без повышенных прав из установщика с повышенными правами только для разрешения пути к исходной папке пользовательских документов.

Использовать ExecAsOriginalUser функция

Вы должны обменяться путем между установщиками через некоторый временный файл, который доступен для обеих учетных записей. Например, файл в {commondocs}, как видно из Inno Setup, всегда устанавливается в каталог администратора AppData.

[Files]
Source: "*.txt"; DestDir: "{code:GetUserDocumentsFolder}"

[Code]

var
  UserDocumentsFolder: string;

function GetUserDocumentsFolder(Params: string): string;
begin
  Result := UserDocumentsFolder;
end;

function InitializeSetup(): Boolean;
var
  TempFile: string;
  Code: string;
  Buf: TArrayOfString;
  ResultCode: Integer;
begin
  Result := True;

  TempFile := { some path accessible by both users };
  Code :=
    '[Environment]::GetFolderPath(''MyDocuments'') | ' +
    'Out-File "' + TempFile + '" -Encoding UTF8';
  Log(Format('Executing: %s', [Code]));
  if (not ExecAsOriginalUser('powershell.exe', Code, '', SW_HIDE,
                             ewWaitUntilTerminated, ResultCode)) or
     (ResultCode <> 0) or
     (not LoadStringsFromFile(TempFile, Buf)) then
  begin
    MsgBox('Failed to resolve user MyDocuments path', mbError, MB_OK);
    Result := False;
  end
    else
  begin
    UserDocumentsFolder := Buf[0];
    Log(Format('User Documents path resolved to "%s"', [UserDocumentsFolder]));
  end;
end;

Связанные обсуждения:

Другие вопросы по тегам