Directory NN is in the user profile, but is not listed in the RemoveFile table - wix

When I am trying to create the installer i am getting the following error:
The directory ProgramMenuDir is in the user profile but is not listed in the RemoveFile table.
How do I resolve this issue? Below is the directory structure I am using:
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="E">
<Directory Id="Monarch" Name="Monarch">
<Component Id="Monarch" Guid="*">
<RemoveFolder Id='Monarch' On='uninstall' />
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]'
Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
</Directory>

As far as I can see, the problem is in the usage of <RemoveFolder/> element. If the 'Directory' attribute is omitted, it takes the directory of the parent component. In your case, it is a directory with Id="EFIMonarch". This explains why you get the warning for the outer directory (ProgramMenuDir), but don't get it for EFIMonarch directory.
Try replacing:
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
with
<RemoveFolder Id='RemoveProgramMenuDir' Directory='ProgramMenuDir' On='uninstall' />
Also, it is a good idea to be explicit for every RemoveFolder element.
Hope this helps.

If other answers are still not working for you, try to check Suppress ICE validation option, Visual studio will ignore these validations, just follow this route:
YourProject -> Properties -> Tool Settings

Just writing this up for some others who may still experience this problem even after following the answer for this question.
I had the same problem, and even after explicitly specifying the Directory in the RemoveFolder did not help me, I tried to put this DirectoryRef containing the shortcut install/uninstall somponents right after the TARGETDIR within the same fragment and it helped fix my issue.

If following answer still still not working. Try to reboot your visual studio.

Related

WIX :Adding a shortcut to StartMenu folder Windows 10

I have an application that will install a shortcut to Start Menu folder. It is working perfectly in Win7. But shortcut is not coming when I install the application in Windows 10 machine. The shortcut entry in my WIX file is given below.
<Component Id="cmptest" Guid="*" KeyPath="yes">
<Shortcut Id="test.exe2" Directory="StartMenuFolder"
Name="test" Target="[#test.exe]" Hotkey="0" IconIndex="0" Show="normal" />
</Component>
Before getting into too much detail:
Are you sure the shortcut really isn't there? The Windows 10 start menu is so strange that I find I have to look twice very often to find shortcuts that are actually there. Just checking.
For that matter, are you sure the install actually completes in Windows 10? Perhaps it rolls back and you didn't notice?
The Directory StartMenuFolder does not compile for my test project, until I add it as a directory under TARGETDIR myself:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="StartMenuFolder" />
</Directory>
I assume you already have this folder added there to make your setup compile. You could also try ProgramMenuFolder for testing and see if the shortcut shows up.
Where is the rest of your WiX source? I can't see if you actually install the file you reference: #test.exe? Does the component that hosts that file actually get installed on Windows 10?
And for some extra strangeness: I haven't seen this much, but since the problem manifests itself on Windows 10, maybe have a read of this answer and see if it rings any bells: Wix Uninstall Shortcut not working
Essentially some shortcuts are hidden auto-magically in Windows 8 and probably upwards. I don't see any reason why your shortcut should be hidden though.
I have been able to get the shortcuts for to show up using the ProgramMenuFolder suggested by Stein Asmul for testing. Below is my setup which is working, with the exception being that my icons not showing up.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Barcode Printer App" />
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="BarcodePrinterAppShortcuts" Name="Barcode Printer App" />
</Directory>
</Directory>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Id="BarcodeAppExe" Source="$(var.BarcodePrinterHelperApp.TargetPath)" >
<Shortcut Id="BarcodeAppShortcut"
Directory="BarcodePrinterAppShortcuts"
Name="Barcode Printer App"
WorkingDirectory="INSTALLFOLDER"
Advertise="yes"
Icon="icon.ico"
IconIndex="0"
>
</Shortcut>
</File>
<RemoveFolder Id="DeleteTheBarcodeAppShortcut"
Directory="BarcodePrinterAppShortcuts"
On="uninstall" />
</Component>
</ComponentGroup>
<Component Id="UninstallShortcut" Guid="*" Directory="BarcodePrinterAppShortcuts">
<Shortcut Id="UninstallThisProduct"
Name="Uninstall Barcode Printer App"
Description="Uninstalls Barcode Printer App"
Target="[System64Folder]msiexec.exe"
Arguments="/x [ProductCode]" />
<RegistryValue Root="HKCU" Key="Software\Powerserve\BarcodePrinterApp" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
It could be permission issue. Try to run your installation As Administrator (or, open Command Prompt as Administrator) and run your installation from there. Also, you may want to check User Account Control settings and lower the slider if it's too restrictive.

How do I remove files and Folders from ProgramData Folder on Uninstall

Hi there I am having a problem getting my Wix installer to remove elements on Uninstall. The problem folders and files are located on our corporate specified programdata folder 'D:\programdata'. The folders get created OK, however will not remove on Uninstall. The folder structure is as follows
D:\programdata
Company Name
App Name
Logs
QueryOutput
The following is an excerpt from the relevant section of the product.wxs file:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="CommonAppDataFolder" Name="CommonAppData" >
<Directory Id="dirCompanyAppData" Name="Company Name">
<Directory Id="dirAppNameAppData" Name="AppName">
<Component Id="cmpDirCommonAppData" Guid="{F808944A-D898-43F3-BA1D-A35A3FD7DF41}" KeyPath="yes">
<CreateFolder Directory="dirAppNameAppData" />
<RemoveFile Id="PurgeAppName" Name="*.*" On="uninstall" />
<RemoveFolder Id="idDirAppNameAppData" On="uninstall" Directory="dirAppNameAppData" />
</Component>
</Directory>
<Component Id="cmpDirCompanyName" Guid="{A1E7E75A-D582-40C5-BD6B-D36BFB11795E}" KeyPath="yes">
<RemoveFile Id="PurgeCompanyName" Name="*.*" On="uninstall" />
<RemoveFolder Id="idDirCompanName" On="uninstall" Directory="dirCompanyNameAppData" />
</Component>
</Directory>
</Directory>
<Directory Id="ProgramFilesFolder">
... etc
Note company and application identifying elements have been replaced in the code. I have left out the remainder of the wxs file for brevity and because I believe the relevent code is included in this extract. Any assistance much appreciated, this has me stumped.
Kind Regards
Paul J.
From RemoveFolder definition:
Remove an empty folder if the parent component is selected for installation or removal.
In your case the AppData folder probably has user specific configuration in it like it is supposed to.
I think all the component planning is done first, then executed. So, RemoveFile will plan all the files in that folder to be removed and RemoveFolder will decide it shouldn't delete the folder because at the time of planning, the folder still has stuff in it that is not part of the installation included components and therefore not empty.
You will need to use util:RemoveFolderEx. Again there is another caveat to using this.
Because it might dramatically affect Windows Installer's File Costing, the temporary rows must be written before the CostInitialize standard action. Unfortunately, MSI doesn't create properties for the Directory hierarchy in your package until later, in the CostFinalize action.
So you need to manually set a directory based off of a property you probably read from the registry before the WixRemoveFoldersEx action which I think is scheduled just before CostInitialize.

WiX Proper Creation of Desktop Shortcut

There are two answers on Create shortcut to desktop using WiX
Both these answers lack any real explanation of what is going on. What is the difference between these two methods of creating shortcuts? The first method falls in line with WiX - Create shortcut documentation.
The second method has a MergeRedirectFolder which I can't seem to find any documentation on, and I don't understand why the second example doesn't require the registry setting since according to WiX Documentation, a registry setting:
is required as a Shortcut cannot serve as the KeyPath for a component when installing non-advertised shortcuts for the current users.
Does this mean that the second method is an advertised shortcut? Or is it an answer that assumes the user is installing per machine? Or am I lost in the sauce? (Quite possible - second day trying to use WiX, since Microsoft forced me down this path.)
The first one:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="Text under your icon"
Description="Comment field in your shortcut"
Target="[MYAPPDIRPROPERTY]MyApp.exe"
WorkingDirectory="MYAPPDIRPROPERTY"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software/MyAppName"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</Directory>
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="MyCompany" Name="MyCompany">
<Directory Id="MYAPPDIRPROPERTY" Name="MyAppName">
</Directory>
</Directory>
</Directory>
The second one:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop" />
<Directory Id="MergeRedirectFolder">
<Component Id="MyExeComponent" Guid="*">
<File Id="MyExeFile" Source="$(var.ExeSourcePath)" KeyPath="yes">
<Shortcut
Id="DesktopShortcut"
Directory="DesktopFolder"
Name="$(var.ShortcutName)"
WorkingDirectory="MergeRedirectFolder" />
</File>
</Component>
</Directory>
</Directory>
Caveat: Per Doc's comment, since neither example specified the Advertise attribute, neither should create an advertised shortcut. I don't remember what led me to write the answer below; it seems likely to be incorrect. I'll leave the answer in tact in case there is some subtle truth behind it.
The first example creates an advertised shortcut; the second creates a non-advertised shortcut. The rules for the two types of shortcuts are described with the Shortcut Table Target column.
A non-advertised shortcut is a standard Windows shortcut like you would create with Windows Explorer. An advertised shortcut enhances resiliency by verifying that all the components in the feature are installed when the shortcut is activated.

Removing application use(r)-generated files with WiX

Currently, our user data hierarchy looks like this:
LocalAppDataFolder/Company/Product
This makes sense as far as it goes because a user might have multiple products installed. However, WiX will not let me remove just the Product folder.
<Directory Id="LocalAppDataFolder">
<Directory Id="ManufacturerDir" Name="Company">
<Directory Id="AppDataDir" Name="Product">
<Component Id="AppData" Guid="some_guid">
<RemoveFolder Id="AppDataDir" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Company\Product" Type="string" Value="" />
</Component>
</Directory>
</Directory>
</Directory>
The above snippet causes the error, "LGHT0204 : ICE64: The directory Company is in the user profile but is not listed in the RemoveFile table." Obviously, I don't want to wipe the data from other products. Several examples that I've found are only one directory deep, i.e. they do not include an intervening directory, in this case Company.
I get the feeling that I am misunderstanding something here. What? Many thanks.
Adding <RemoveFolder Id="RemoveManufacturerDir" Directory="ManufacturerDir" On="Uninstall"/> should get rid of that error. The folder will only get removed if the directory is empty. If there are other files in there, it will not be removed.

Per-Machine install problem with User Profile

When building my WXS data into an MSI I get the following error:
ICE38: Component CreateFolder installs to user profile. It must use a registry key under HKCU as its KeyPath, not a file.
This is confusing me cause I have my project set to be a per-machine installation, so from my understanding it should install to the "C:\Users\All Users" or "C:\Users\Default" not to the actual user profile. I have tried a couple of different methods to say it is a per-machine installation, but none of them work. Any thoughts would be greatly appreciated. I am stumped!
To make it an per-machine I tried these two settings (separately) and neither one worked.
<Property Id="ALLUSERS" Value="2" />
and
<Package InstallScope="perMachine" ... />
EDIT: Code for CreateFolder
<Directory Id="AdminToolsFolder" SourceName="Admin Tools">
<Component Id="CreateFolder" Guid="{452A617E-XXXX-XXXX-XXXX-3710802B3BBD}" KeyPath="yes">
<CreateFolder Directory="AdminToolsFolder" />
</Component>
</Directory>
I wrote up a solution to this problem a while ago: http://robmensching.com/blog/posts/2007/4/27/How-to-create-an-uninstall-shortcut-and-pass-all-the.
If you want to create a shortcut you can use the Shortcut element:
<Directory Id="AdminToolsFolder" SourceName="Admin Tools">
<Component Id="MyShortcuts" Guid="<guid value>">
<Shortcut Id="Shortcut_MyAdminTool" Directory="AdminToolsFolder"
Name="My Admin Tool" Target="[#AdminTool]"
Show="normal" WorkingDirectory="TARGETDIR" />
</Component>
</Directory>