Question

I'm trying to use RemoveFolderEx to delete a folder one level up from my install folder upon uninstall of the app. Here is what I have, but it's not working:

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="MyAppBaseFolder" Name="MyAppID">
          <Directory Id="INSTALLFOLDER" Name="MyAppLauncher">
            <Directory Id="UPDATESCRIPTSFOLDER" Name="Scripts" />
            <Component Id="CleanupMainApplicationFolder" Guid="*">
              <RegistryValue Root="HKLM" Key="SOFTWARE\MyApp ID\MyApp ID Windows Client" Name="Path" Type="string" Value="${path::getfullpath(path::combine([INSTALLFOLDER],'..\MyApp'))}" KeyPath="yes" />
              <util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" />
            </Component>
          </Directory>
        </Directory>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="MyApp ID"/>
      </Directory>
    </Directory>
  </Fragment>

The MSI will build fine, but when I run the setup it seems to be failing on the RegistryValue element and complaining about the ".." in the path. The string I'm making is like: "C:\Program Files (X86)\MyApp ID\MyAppLauncher\..\MyApp". I need it to resolve to: "C:\Program Files (X86)\MyApp ID\MyApp".

I'm not too familiar with the ${path:: ... } stuff. I saw a couple examples with ${path::combine()} so I guess I assumed that would work with getfullpath in .NET. Perhaps it does and my syntax is just wrong?

Thank you!

EDIT: Sorry, I got that ${path::combine... stuff from BUILDING WIX without fully reading what that article is doing. It has nothing to do with a wxs file, it's for NAnt (as Rob mentioned below). So I guess my question simply is this: how can I combine and resolve an absolute and relative path like C:\Program files (X86)\MyApp ID\MyAppLauncher\..\MyApp. Thanks

EDIT2: Thanks again Rob, I was focusing so much on resolving the path I didn't even consider the most obvious solution, which was to simply reference a new <Directory element. I now have it cleaning up 2 folders with the following code:

  <Property Id="APPLICATIONFOLDER">
    <RegistrySearch Key="SOFTWARE\MyApp ID\MyApp ID Windows Client" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
  </Property>

  <Property Id="PRINTERFOLDER">
    <RegistrySearch Key="SOFTWARE\MyApp ID\MyApp ID Printer" Root="HKLM" Type="raw" Id="PRINTERFOLDER_REGSEARCH" Name="Path" />
  </Property>

...

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="MyAppBaseFolder" Name="MyAppID">
          <Directory Id="INSTALLFOLDER" Name="MyAppLauncher">
            <Directory Id="UPDATESCRIPTSFOLDER" Name="Scripts" />
            <Component Id="CleanupMainApplicationFolder" Guid="*">
              <RegistryValue Root="HKLM" Key="SOFTWARE\MyApp ID\MyApp ID Windows Client" Name="Path" Type="string" Value="[LM_INSTALLFOLDER]" KeyPath="yes" />
              <util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" />

              <RegistryValue Root="HKLM" Key="SOFTWARE\MyApp ID\MyApp ID Printer" Name="Path" Type="string" Value="[LMP_INSTALLFOLDER]" />
              <util:RemoveFolderEx On="uninstall" Property="PRINTERFOLDER" />
            </Component>
          </Directory>
          <Directory Id="LM_INSTALLFOLDER" Name="MyApp" >
          </Directory>
          <Directory Id="LMP_INSTALLFOLDER" Name="MyAppPrinter" >
          </Directory>
        </Directory>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="MyApp ID"/>
      </Directory>
    </Directory>
  </Fragment>
Was it helpful?

Solution

The syntax you have in the RegistryValue/@Value looks like NAnt or something. It isn't clear what interprets that but the Windows Installer will not. You have a couple options to get that registry value correct. First, change the RegistryValue element to look like:

<RegistryValue Root="HKLM"
               Key="SOFTWARE\MyApp ID\MyApp ID Windows Client"
               Name="Path"
               Type="string"
               Value="[MyAppBaseFolder]MyApp"
               KeyPath="yes" />

Alternatively, you could define "MyApp" in your Directory tree and reference it directly. That'd look a little like adding the following as a child of MyAppBaseFolder (peer of INSTALLFOLDER):

 <Directory Id='MyAppFolder' Name='MyApp' />

Then updating your RegistryValue element to look like:

<RegistryValue Root="HKLM"
               Key="SOFTWARE\MyApp ID\MyApp ID Windows Client"
               Name="Path"
               Type="string"
               Value="[MyAppFolder]"
               KeyPath="yes" />

I prefer the latter but that's just because I prefer using identifiers without concatenating strings.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top