Inno Setup всегда устанавливается в папку администратора AppData

Я хочу сохранить свое приложение у текущего пользователя AppData каталог, чтобы избежать проблем с разрешениями, которые мы имели при автоматическом обновлении нашего приложения (когда оно хранится в Program Files). Мы не предоставляем пользователю возможность установить приложение. У нас были жалобы от пользователей, не являющихся администраторами, на то, что установщик сохраняет приложение в AppData каталог (после UAC конечно) вместо текущего пользователя AppData каталог, который затем предотвращает запуск приложения в будущем.

Во-первых, я имел DefaultDirName={userappdata}\{#MyAppName}, Потом я попробовал DefaultDirName={commonappdata}\{#MyAppName}, Затем я попробовал это вместе с PrivilegesRequired=lowest и даже как PrivilegesRequired=none так как установщик Make InnoSetup запрашивает повышение привилегий только тогда, когда требуется предложенный вопрос.

На данный момент это мой сценарий на случай, если я упущу что-то очевидное:

; Script generated by the Inno Setup Script Wizard.
;SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Teamwork Chat"
#define MyAppVersion "0.10.0"
#define MyAppPublisher "Digital Crew, Ltd."
#define MyAppURL "http://www.teamwork.com/"
#define MyAppExeName "TeamworkChat.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{0F063485-F5AF-4ADE-A9F9-661AB3BAA661}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppName}
DisableDirPage=yes
DefaultGroupName={#MyAppName}
OutputDir=E:\chat-client\dist
OutputBaseFilename={#MyAppName}_for_Windows32_Installer-{#MyAppVersion}
SetupIconFile=E:\chat-client\icons\teamwork_chat.ico
WizardImageFile=E:\chat-client\icons\chatWizardImageFile.bmp
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "E:\chat-client\dist\TeamworkChat\win32\TeamworkChat.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\ffmpegsumo.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\icudtl.dat"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\libGLESv2.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\nw.pak"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

редактировать

Я изменил два варианта, но все еще не повезло;

PrivilegesRequired=lowest
...
[Icons]
...
Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

Изменить 2:

Я добавил runasoriginaluser флаг и сгенерированный новый AppId (GUID) но все равно не повезло;

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runasoriginaluser

Изменить 3:

Я создал простой репозиторий GitHub с исходными файлами и скриптом Inno.

Изменить 4:

Я тестировал на Windows 8.1. Кажется, что работает, когда скомпилировано на Windows 7 и работает на Windows 8, но не на 8 и 8.

Изменить 5:

Сейчас это решено, но чтобы прояснить ситуацию с Edit 4, он работал не только на моей машине. Это работало на других машинах Windows 8. Должно быть, было какое-то странное кеширование или что-то еще (хотя я изменил AppId).

2 ответа

Решение

Судя по формулировке вашего вопроса и, если я вас правильно понимаю, это звучит так, потому что вы "проверяете учетную запись администратора для запуска установки". Если это так, и вы вводите другую учетную запись (из той, в которую вы вошли) в приглашении UAC, то текущий пользователь фактически становится учетной записью администратора, которую вы только что ввели в приглашении UAC, а не учетной записью, в которую вы вошли. в с. Следовательно, до тех пор, пока вас просят повысить уровень установки с помощью UAC, он не будет попадать в каталог AppData зарегистрированного пользователя.

Что вам может понадобиться, это использовать runasoriginaluser функция, которая будет использовать учетные данные вошедшего в систему пользователя вместо учетной записи, которую вы указали в приглашении UAC, или найти причину повышения прав UAC.

Смотрите также Inno Setup Создание раздела реестра для вошедшего в систему пользователя (не администратора).

Документация MSDN по контексту установки также может быть полезна.

Должно работать с PrivilegesRequired=lowest, И это правильный подход. Если это не так, мы хотим увидеть файл журнала.

lowest заставит установщик работать в контексте текущего непривилегированного пользователя. Отсюда все константы, как {userappdata}, {userdesktop} и т. д. будет относиться к текущему пользователю.


В любом случае, чтобы ответить на ваш вопрос, вы можете использовать код ниже.

Но это только для особых ситуаций, когда установщику действительно нужны права администратора (например, для регистрации некоторой системной DLL), но все же необходимо развернуть файлы для исходного пользователя. Как здесь: Inno Setup - Регистрация компонентов в качестве администратора.

[Files]
Source: "MyProg.exe"; DestDir: "{code:GetAppData}"

[Code]

var
  AppDataPath: string;

function GetAppData(Param: string): string;
begin
  Result := AppDataPath;
end;  

function InitializeSetup(): Boolean;
var
  Uniq: string;
  TempFileName: string;
  Cmd: string;
  Params: string;
  ResultCode: Integer;
  Buf: AnsiString;
begin
  AppDataPath := ExpandConstant('{userappdata}');
  Log(Format('Default/Fallback application data path is %s', [AppDataPath]));
  Uniq := ExtractFileName(ExpandConstant('{tmp}'));
  TempFileName :=
    ExpandConstant(Format('{commondocs}\appdata-%s.txt', [Uniq]));
  Params := Format('/C echo %%APPDATA%% > %s', [TempFileName]);
  Log(Format('Resolving APPDATA using %s', [Params]));
  Cmd := ExpandConstant('{cmd}');
  if ExecAsOriginalUser(Cmd, Params, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
     (ResultCode = 0) then
  begin
    if LoadStringFromFile(TempFileName, Buf) then
    begin
      AppDataPath := Trim(Buf);
      Log(Format('APPDATA resolved to %s', [AppDataPath]));
    end
      else
    begin
      Log(Format('Error reading %s', [TempFileName]));
    end;
    DeleteFile(TempFileName);
  end
    else
  begin
    Log(Format('Error %d resolving APPDATA', [ResultCode]));
  end;

  Result := True;
end;

Больше похожих вопросов:

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