簡體   English   中英

Inno Setup - 從需要特權的安裝程序訪問非特權帳戶文件夾

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

我使用 Inno Setup 來安裝文檔/文件而不是應用程序,這主要適用於 Windows 7 用戶。 因此,我的DestDir基於{userdocs}因此所有文件都將安裝在該用戶的 Documents 庫下的文件夾中。

當我使用相同的安裝程序安裝 TTF 字體時,就會出現問題。 這需要提升的權限( adminsuperuser )。 我看到的問題是,如果非管理員用戶運行安裝,他們會通過 UAC 正確提示輸入管理員/超級用戶密碼......但此時安裝的DestDir更改為 Admin 文檔文件夾而不是用戶的文檔文件夾。 有沒有辦法解決這個問題或防止這種情況發生?

例如,非管理員帳戶Fre的文檔路徑為:

C:\Users\Fred\My Documents\

如果我不將 TTF 字體作為安裝的一部分,這就是安裝程序將用作安裝{userdocs}的基本路徑的內容,並且它可以完美運行。

如果我確實將 TTF 字體作為安裝的一部分包含在同一非管理員用戶 Fred 的安裝中,則在安裝完成時{userdocs}已成為

C:\Users\AdminUser\My Documents\ 

...這不是預期的結果...只需要字體安裝部分的管理員權限,並且需要將文件安裝到實際用戶的文檔區域中。

謝謝。

使用PrivilegesRequired=admin指令為字體創建子安裝程序,您將從主非提升安裝程序中運行該子安裝程序。

主安裝程序代碼將如下所示:

[Setup]
PrivilegesRequired=lowest

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

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

當然,您應該從主卸載程序卸載子安裝程序。

您可能還想確保用戶沒有明確以管理員權限運行主安裝程序。 請參閱我對如何在用戶使用“以管理員身份運行”時使用安裝程序寫入用戶的我的文檔目錄的回答。

另一種實現方法是使用帶有runas動詞的ShellExec函數來執行提升的外部復制實用程序( copyxcopyrobocopy )。 請參閱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;

相關討論:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM