Inno Setup is always installed in the AppData admin directory

I want to save my application in the current AppData directory to avoid problems with permissions that we had when updating our application automatically (when it was stored in Program Files). We do not provide the user with the ability to install the application. We had complaints from non-admin users that the installer stores the application in the admin directory of AppData (after UAC, of โ€‹โ€‹course) instead of the current user, AppData , which then prevents the application from starting in the future.

Firstly, I had DefaultDirName={userappdata}\{#MyAppName} . Then I tried DefaultDirName={commonappdata}\{#MyAppName} . Then I tried this together with PrivilegesRequired=lowest and even as PrivilegesRequired=none how to Make InnoSetup installer request privilege privilege only if necessary .

This is my script, as of right now, if I miss something obvious:

 ; 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 

Edit

I changed two options, but still no luck;

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

Edit 2:

I added the runasoriginaluser flag and generated a new AppId (GUID), but still no luck;

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

Edit 3:

I created a simple GitHub repository with source files and an Inno script.

Change 4:

I tested Windows 8.1. It seems to work when compiling on Windows 7 and runs on Windows 8, but not when compiling on 8 and works on 8.

Change 5:

Now he has decided, but to understand Edit 4, he worked not only on my machine. It worked on other Windows 8 machines. There must have been some weird caching or something like that (although I changed the AppId ).

+6
source share
2 answers

From the wording of your question, and if I understand you correctly, it sounds like this because you are "checking the administrator account to run the installation." If this is the case, and you enter another account (from the one with which you are logged in) at the UAC prompt, the current user actually becomes the administrator account that you just entered at the UAC prompt, and not the account that you registered in s. Therefore, until you are asked to raise the installation using UAC, it will not get into the registered directory of the AppData user.

You may need to use the runasoriginaluser function, which will use the registered user credentials rather than the account entered at the UAC prompt, or find what triggers the UAC boost prompt.

See also Inno Setup Create a registry key for a registered user (not an administrator) .

The MSDN documentation on the Installation Context may also be useful.

+3
source

It should work with PrivilegesRequired=lowest . And this is the right approach. If this is not the case, we want to see the log file.

lowest will make the installer work in the context of the current unprivileged user. Therefore, constants , such as {userappdata} , {userdesktop} , etc., will refer to the current user.


In any case, you can use the code below to answer your question.

But this is just for special situations when the installer really needs administrator privileges (for example, to register some system DLL), but you still need to deploy the files for the original user. Like here: Inno Setup - Register components as administrator .

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

Other related questions:

+2
source

Source: https://habr.com/ru/post/915370/


All Articles