Inno Setup always installs into admin's AppData directory

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I want to store my app in the current user's AppData directory to avoid problems with permissions we had when auto-updating our app (when it's stored in Program Files). We don't give the user the option of where to install the app. We've had complaints from non-admin users that the installer stores the app in the admin's AppData directory (after UAC of course), instead of the current user's AppData directory, which then prevents the app from running in the future.

Firstly, I had DefaultDirName={userappdata}\{#MyAppName}. Then I tried DefaultDirName={commonappdata}\{#MyAppName}. Then I tried that along with PrivilegesRequired=lowest and even as PrivilegesRequired=none as the Make InnoSetup installer request privileges elevation only when needed question suggested.

This is my script as of right now in case I'm missing 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've changed two options but still no luck;

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

Edit 2:

I've 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've created a simple GitHub repository with the source files and Inno script.

Edit 4:

I had been testing on Windows 8.1. It seems to work when compiled on Windows 7, and ran on Windows 8, but not when compiled on 8 and ran on 8.

Edit 5:

It's solved now but to clear things up regarding Edit 4, it wasn't working only on my machine. It worked on other Windows 8 machines. Must've been some weird caching or something (even though I changed the AppId).

回答1:

From the wording of your question and if I am understanding you correctly, it sounds like this is because you are "validating with an admin account for the install to run." If this is the case and you are entering a different account (from that which you are logged in with) at the UAC prompt, the current user then actually becomes the Administrator account you just entered at the UAC prompt and not the account you are logged in with. Therefore, as long as you are being asked to elevate the installation using UAC, it will not end up in the logged in user's AppData directory.

What you may need to do is use the runasoriginaluser function, which will use the logged in user credentials instead of the account you entered at the UAC prompt, or find what is causing the UAC elevation prompt.

See also Inno Setup Creating registry key for logged in user (not admin user).

The MSDN documentation on Installation Context may also be useful.



回答2:

It should work with PrivilegesRequired=lowest. And it's the correct approach. If it does not, we want to see a log file.

The lowest will make the installer run within context of the current unprivileged user. Hence all constants, like {userappdata}, {userdesktop}, etc, will refer to the current user.


Anyway, to answer your question, you can use the code below.

But that's just for special situations, when the installer really needs administrator privileges (e.g. to register some system DLL), but still needs to deploy files for the original user. Like here: Inno Setup - Register components as an 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; 

More similar questions:



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!