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;
Больше похожих вопросов: