Inno Setup - 从需要特权的安装程序访问非特权帐户文件夹

Inno Setup - Access unprivileged account folders from installer that requires privileges

我正在使用 Inno Setup 安装 documents/files 而不是应用程序,这主要用于 Windows 7 位用户。因此,我的 DestDir 基于 {userdocs},因此所有文件都将安装在该用户的文档库下的文件夹中。

当我使用相同的安装程序安装TTF 字体时出现问题。这需要更高的权限(adminsuperuser)。我看到的问题是,如果非管理员用户运行安装,他们会通过 UAC 正确提示输入 admin/superuser 密码...但此时安装的 DestDir 更改为Admin 文档文件夹而不是用户的文档文件夹。有什么方法可以解决这个问题或防止它发生吗?

例如,非管理员帐户 Fre 的文档路径为:

C:\Users\Fred\My Documents\

如果我没有将 TTF 字体作为安装的一部分,这就是安装程序将用作安装的基本路径的内容 {userdocs} 并且它可以完美运行。

如果我使用相同的非管理员用户 Fred 将 TTF 字体作为安装的一部分,则在安装完成时 {userdocs} 已变为

C:\Users\AdminUser\My Documents\ 

...这不是预期的结果...只需要字体安装部分的管理员权限,并且需要将文件安装到实际用户的文档区域中。

谢谢。

使用 PrivilegesRequired=admin directive 创建字体的子安装程序,您将从主 non-elevated 安装程序中 运行。

主安装程序代码如下:

[Setup]
PrivilegesRequired=lowest

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

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

当然,您应该从主卸载程序中卸载子安装程序。

您可能还想确定,用户没有 运行 明确具有管理员权限的主安装程序。请参阅我对 How to write to the user's My Documents directory with installer when the user used 'Run As Administrator'.

的回答

另一种实现方式是使用ShellExec function with runas verb to execute an elevated external copy utility (copy, xcopy, robocopy). See Inno Setup - Register components as an administrator(运行s regsvr32,但概念是一样的)。


另一种选择是从提升的安装程序执行 non-elevated 进程,只解析原始用户文档文件夹的路径。

使用 ExecAsOriginalUser function.

您必须通过一些两个帐户都可以访问的临时文件来交换安装程序之间的路径。例如。 {commondocs}, as can be seen in the .

中的一个文件
[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;

相关讨论:

  • How to write to the user's My Documents directory with installer when the user used 'Run As Administrator'
  • Make Inno Setup installer request privileges elevation only when needed