How do I install to LocalAppData folder?
Asked Answered
V

4

26

Following directory setting works perfectly for me.

<Directory Id='TARGETDIR' Name='SourceDir'>
  <Directory Id="ProgramFilesFolder">
    <Directory Id='INSTALLDIR' Name='MyApp'/>
  </Directory>
</Directory>

However, when I tried changing "ProgramFilesFolder" to "LocalAppDataFolder", I got lots of error when using light to link and generate my msi:

D:\runGroup.wxs(53) : error LGHT0204: ICE38: Component cmpA5561BE36D80EB58252E69DDA0C2FF8C installs to user profile. It must use a registry key under HKCU as its KeyPath, not a file. D:\main.wxs(38) : error LGHT0204 : ICE64: The directory INSTALLDIR is in the user profile but is not listed in the Remove File table.

Looks like "LocalAppDataFolder" is not acceptable for WiX, while I believe it is one of the system folder properties which defined in here.

What am I supposed to use for LocalAppData folder?

Virtually answered 24/8, 2012 at 3:27 Comment(4)
My advice: don't install to any userprofile folder at all. Install to [ProgramFilesFolder] and allow the operating system to do any redirecting. Each OS could do this differently and your "under the hood fixes" will undoubtedly backfire. If the folder isn't redirected by the OS, MSI reference counting should be able to take care of several installations for different users to the same folder. Just make sure you don't have any read/write files that you modify in the folder. Your installation folder should be read/only. Don't fight Windows's idiosyncrazies - it bites back with a vengeance.Sullivan
The problem here is, I don't know how to let [ProgramFilesFolder] redirect to the place it should be for per-user installation. That's why I had to find out workaround.Virtually
Yes, and you shouldn't redirect it at all :-). Windows might redirect you yet again, and in different ways on Vista, Windows 7, Windows 8 etc... Windows Installer is dangerous to fight with - it fights back. You can still install to [ProgramFilesFolder] even for a per user install, and some Windows versions might automatically redirect it, others might install to ProgramFilesFolder. Don't mess with this, just let it work the way Windows dictates.Sullivan
We need to build a msi for per-user installation on Win 7 without requesting admin privilege. It's tested that in my Win 7 the [ProgramFilesFolder] is resolved as C:\Program Files (x86), which must need admin privilege, that doesn't meet our requirement.Virtually
F
13

I converted an application from being a perMachine install to be a perUser install. In order to properly convert the install I had to add a registry key for each of the components I have.

Originally I had the following:

<Component Id="C.MyExe">
  <File Id="Fi.MyExe" Name="$(var.MyExe.TargetFileName)" Source="$(var.MyExe.TargetPath)" DiskId="1">
    <Shortcut Id="SC.StartMenu"
              Directory="D.ApplicationMenuDir"
              Name="$(var.AppName)"
              WorkingDirectory="INSTALLDIR"
              Icon="MY_ICON.ico"
              IconIndex="0" 
              Advertise="yes"
      />
      ...

When I moved the exe component to the user install I had to do something like this:

<Directory Id="LocalAppDataFolder" Name="AppData">
  <Directory Id="MyAppDirectory" Name="$(var.AppName)">
    <Component Id="C.MyExe" Guid="{MY_GUID}">
      <CreateFolder />
      <RemoveFolder Id="RemoveMyAppDirectory" On="uninstall" />
      <RegistryKey Root="HKCU" Key="Software\MyCompany\MyApp">
        <RegistryValue Name="MainExe" Value="1" KeyPath="yes" Type="integer" />
      </RegistryKey>
      <File Id="Fi.MyExe" Name="$(var.MyExe.TargetFileName)"
          Source="$(var.MyExe.TargetPath)" DiskId="1" Checksum="yes">
      </File>
    </Component>
   ...

The most important part is that you will have to add a registry key which points to HKEY_CURRENT_USER. I added a registry value for each component which indicates that the component is installed.

I also had to remove the following: Advertise="yes".

Ferdinana answered 6/9, 2013 at 19:55 Comment(1)
I was told that you can ignore ICE38 as that's only valid for mixed per-user/per-machine locations and not valid for a pure per-user install. See here.Pyrrho
V
4

Ok, just found that we can do it by overwriting "ProgramFilesFolder":

<SetProperty Id="ProgramFilesFolder" Value="[LocalAppDataFolder]" Before="CostFinalize"><![CDATA[NOT Privileged]]></SetProperty>

Another thing to do is, in <Package> we need to set InstallPrivileges to limited.

Well, I can see no reason why "ProgramFilesFolder" can be used directly while "LocalAppDataFolder" can't.

Virtually answered 24/8, 2012 at 7:19 Comment(6)
Because you don't need to do this. It automatically redirects on Win7.Godsey
The ProgramFilesFolder is not redirecting in my Win7. I tried InstallPrivileges with both 'limited' and default value, all set the %ProgramFilesFolder% to C:\Program Files (x86). How do I trigger this redirecting? And another question, note that in WixUI_Advanced, it explicitly set install path for per-user to %LocalAppData%\Apps\ProgramName. So which is the offically stated version of a program should be installed to for per-user? %LocalAppData%\Apps, or %LocalAppData%\Programs?Virtually
Deqing, this solution looks dangerous - I am surprised Windows Installer will actually let you do it.Sullivan
@Glytzhkof If you look at WixUI_Advanced's code you will find it also set install path to %LocalAppData% for per-user.Virtually
I added a comment to tronda's answer. You can use %LocalAppData% direct. Just ignore ICE38 in your project. I was told ICE38 is invalid for a per-user install. See my answer.Pyrrho
@Virtually did you need to also add RegistryKeys or simply adding this SetProperty and the attributes to the PAckage was enough?Arose
P
3

I had this problem recently. I wanted to convert my installer from per-machine to a per-user but was getting ICE38. I asked on wix-users and one opinion was that you can ignore ICE38 because that was meant as a check for per-machine installs.

See the discussion at wix-users.

Since that is the case, ICE38 is (in my opinion) incorrect and you will want to ignore it. ICE38 implies you are installing per-user resources in the context of a per-machine installation but never verifies that this is so.

Actually authoring a per-user install requires that you ignore ICE38 because it won't ever be accurate for that world.

[Edit] Looks like you got help here.

From Peter Shirtcliffe:

This is my own, admittedly inexpert, understanding of per-user installations:

Installing to subdirectory of LocalAppDataFolder is perfectly OK in a per-user MSI. Because of certain scenarios relating to roaming users, you need to add components containing elements for any directories you create under LocalAppDataFolder. That's why ICE64 is appearing.

The ICE38 error is slightly misleading: since you have a per-user installation, it's safe to ignore as long as the user cannot pick an alternative installation location that is common to all users. ICE38 is checking for the situation where multiple users all install the same component to the same path.

Just posting to help other people (like me).

Pyrrho answered 18/2, 2014 at 15:12 Comment(2)
links are broken... help here would be to post here directly how to ignore the ICE38 error.Arose
@Arose The pertinent stuff from the links are posted below each link above. Neithe addresses how to hide the ICE. There's a way to get the IDE to ignore ICEs if you don't want to see it at all but I don't remember now how to do that.Pyrrho
G
1

Are you installing per-user or per-machine? Also, what OS versions are you targetting? You might want to read:

Authoring a single package for Per-User or Per-Machine Installation context in Windows 7

Godsey answered 24/8, 2012 at 12:40 Comment(5)
I'm installing per-user, that's why I need LocalAppData in the directory structure. And it will be installed on Win7. For me the only way to do is to use SetProperty as I described before.Virtually
According to that article, Per-User installs on Win7 using ProgramFilesFolder will automatically redirect to LocalAppData\Programs. Does this not work for you?Godsey
I just created a test per-user install using InstallShield and set it up using [ProgramFilesFolder]My Company Name\My Product Name and sure it enough it installed to C:\Users\chrpai\AppData\Local\Programs\My Company Name\My Product NameGodsey
I'm not using InstallShield to set up my project. Maybe it will help understanding if you post key code of the wxs which generated by InstallShield.Virtually
InstallShield doesn't generate wxs. (What a freaking shame though.) InstallShield and WiX both generate Windows Installer databases. Therefore the underlying concepts are the same. I have a few things to do today but I'll try to post a sample tonight.Godsey

© 2022 - 2024 — McMap. All rights reserved.