2017-02-15 99 views
2

我使用Inno安装程序安装文档/文件而不是应用程序,这主要针对Windows 7用户。因此,我的DestDir基于{userdocs},因此所有文件都将安装在该用户文档库下的文件夹中。Inno安装程序 - 从安装程序访问需要特权的非特权帐户文件夹

当我使用相同的安装程序安装TTF字体时出现问题。这需要提升特权(adminsuperuser)。我看到的问题是,如果非管理员用户运行安装,则通过UAC正确提示管理员/超级用户密码...但在此时安装的DestDir更改为Admin文档文件夹,而不是用户的文档文件夹。有什么办法可以解决这个问题或防止这种情况发生?

例,非管理员帐户Fre具有的文件路径:

C:\Users\Fred\My Documents\ 

如果我不包括TTF字体作为安装的一部分,这就是安装程序会为基础路径使用对于安装{userdocs}和它完美的作品。

如果我不包括TTF字库与同一非管理员用户Fred在安装过程中,由安装完成{userdocs}已成为

C:\Users\AdminUser\My Documents\ 

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

感谢。

+0

我已经添加了一个示例实现。 –

回答

1

为字体创建子安装程序,其中PrivilegesRequired=admin directive将从主非升级安装程序中运行。

主安装程序代码将是这样的:

[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动词runas执行升高的外部复制实用程序(copyxcopyrobocopy)。见Inno Setup - Register components as an administrator(它运行regsvr32,但概念是相同的)。


另一种选择是从提升的安装程序执行未升级的进程,仅解析到原始用户文档文件夹的路径。使用ExecAsOriginalUser function

您必须通过两个帐户均可访问的临时文件来交换安装程序之间的路径。例如。 {commondocs}中的一个文件,可以在Inno Setup always installs into admin's AppData directory中看到。

[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; 

相关讨论:

+0

第一个选项适合我的情况。非常感谢你。 –

相关问题