I have a WiX project in visual studio that contains two files: Product.wxs and config.wxi.
When I attempt to build this project, I get the following error: "Undefined preprocessor variable '$(var.ProductName)'."
What am I doing wrong here that the Include file is apparently not being recognized?
config.wxi
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?Define Manufacturer = "My Company" ?>
<?Define ProductName = "My Product" ?>
<?Define Version = "1.0.0.0" ?>
<?Define BuildType = "Development" ?>
<?Define BuildTypeShort = "Dev" ?>
</Include>
Product.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include config.wxi ?>
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" UpgradeCode="6e7efd44-0149-416b-871d-418ba6365e1b">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="MySetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ManufacturerFolder" Name="$(var.Manufacturer)">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Source="$(var.SomeProjectA.TargetPath)"/>
<File Source="$(var.SomeProjectB.TargetPath)"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Use "define" instead of "Define".
As here:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define Manufacturer = "My Company" ?>
<?define ProductName = "My Product" ?>
<?define Version = "1.0.0.0" ?>
<?define BuildType = "Development" ?>
<?define BuildTypeShort = "Dev" ?>
</Include>
Related
As I mentioned in the title I need to do reverse engineering with a .msm file, this MSM file contains a class table and a progId table and I can't find any simple code example of how to do it.
If I put class and progId in "File", I only get a new entry in the registry table. That someone could give me a simple example but with all the Wix?
Use Class and ProgId elements with their Advertise attributes set to yes.
The WiX Class doc says:
Set this value to "yes" in order to create a normal Class table row.
I used IsWiX and heat to generate this short POC. Heat originally authored the Class element as a child of the File element but that isn't allowed when setting Advertise to yes like Bob said to do. I used some random Windows OCX file because I don't author COM components these days.
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ComponentRules="OneToOne"?>
<!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module -->
<?define SourceDir="..\Deploy"?>
<Module Id="MergeModule1" Language="1033" Version="1.0.0.0">
<Package Id="ae2940bf-2a96-409f-8828-43732e8eec3d" Manufacturer="MergeModule1" InstallerVersion="200" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="owc1342753EC14FB934098148748894FC8C" Guid="cb00efc4-e09b-8162-9ee7-2f0d2982bab0" >
<Class Id="{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}" Context="InprocServer32" Description="ScriptControl Object" ThreadingModel="apartment" Version="1.0" Programmable="yes" Control="yes" Advertise="yes">
<ProgId Id="MSScriptControl.ScriptControl.1" Description="ScriptControl Object">
<ProgId Id="MSScriptControl.ScriptControl" Description="ScriptControl Object" />
<ProgId Id="ScriptControl" Description="ScriptControl Object" />
</ProgId>
</Class>
<File Id="owf1342753EC14FB934098148748894FC8C" Source="$(var.SourceDir)\msscript.ocx" KeyPath="yes">
<TypeLib Id="{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}" Description="Microsoft Script Control 1.0" HelpDirectory="MergeRedirectFolder" Language="0" MajorVersion="1" MinorVersion="0" Advertise="yes">
<Interface Id="{0E59F1D3-1FBE-11D0-8FF2-00A0D10038BC}" Name="IScriptControl" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{70841C6F-067D-11D0-95D8-00A02463AB28}" Name="IScriptModuleCollection" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{70841C70-067D-11D0-95D8-00A02463AB28}" Name="IScriptModule" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{70841C71-067D-11D0-95D8-00A02463AB28}" Name="IScriptProcedureCollection" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{70841C73-067D-11D0-95D8-00A02463AB28}" Name="IScriptProcedure" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{70841C78-067D-11D0-95D8-00A02463AB28}" Name="IScriptError" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="{8B167D60-8605-11D0-ABCB-00A0C90FFFC0}" Name="DScriptControlSource" ProxyStubClassId32="{00020420-0000-0000-C000-000000000046}" />
</TypeLib>
</File>
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\Implemented Categories\{0DE86A52-2BAA-11CF-A229-00AA003D7352}" Value="" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\Implemented Categories\{0DE86A53-2BAA-11CF-A229-00AA003D7352}" Value="" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\Implemented Categories\{0DE86A57-2BAA-11CF-A229-00AA003D7352}" Value="" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\Implemented Categories\{40FC6ED4-2438-11CF-A3DB-080036F12502}" Value="" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\Implemented Categories\{40FC6ED5-2438-11CF-A3DB-080036F12502}" Value="" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\MiscStatus\1" Value="132499" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\MiscStatus" Value="0" Type="string" Action="write" />
<RegistryValue Root="HKCR" Key="CLSID\{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}\ToolboxBitmap32" Value="[#owf1342753EC14FB934098148748894FC8C],102" Type="string" Action="write" />
</Component>
</Directory>
</Directory>
<ComponentGroupRef Id="Custom" />
</Module>
</Wix>
I'm using CPACK and something like this for my WiX3 installer to create a nested start menu folder like My Company/My Product:
<Product>
... etc ...
<DirectoryRef Id="ProgramMenuFolder">
<Directory Id="ProgramMenuVendorFolder" Name="My Company">
<Directory Id="ProgramMenuProductFolder" Name="My Product"/>
</Directory>
</DirectoryRef>
<!-- shortcuts to applications in the start menu -->
<DirectoryRef Id="ProgramMenuProductFolder">
<Component Id="ProgramMenuShortcutsComponent" Guid="$(var.CPACK_WIX_PRODUCT_GUID)">
<CreateFolder Directory="ProgramMenuVendorFolder" />
<CreateFolder Directory="ProgramMenuProductFolder" />
<RemoveFolder Id="RemoveProgramMenuVendorFolder" Directory="ProgramMenuVendorFolder" On="uninstall" />
<RemoveFolder Id="RemoveProgramMenuProductFolder" Directory="ProgramMenuProductFolder" On="uninstall" />
<Shortcut Id="MainShortcut" Name="My Product" Target="path/to/the/executable.exe" Directory="ProgramMenuProductFolder" />
<!-- RegistryValue whichs serves as KeyPath -->
<RegistryValue
Root="HKCU"
Key="Software\$(var.CPACK_PACKAGE_VENDOR)\$(var.CPACK_PACKAGE_NAME)"
Name="InstalledStartMenuShortcuts"
Type="integer"
Value="1" />
</Component>
</DirectoryRef>
... etc ...
</Product>
Unfortunately it fails:
main.wxs(32) : error LGHT0204 : ICE21: Component: 'ProgramMenuShortcutsComponent' does not belong to any Feature.
What does this mean, and what should I add/remove ?
You need to add a ComponentRef under the Feature you want to control the install of your Component.
I have the following XML content:
<fragment>
<directory Id="dirABC" Name="ABC">
<component Id="cmpA" Guid="*">
<file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe" />
</component>
<component Id="cmpB" Guid="*">
<file Id="filB" KeyPath="yes" Source="SourceRootDir\BBB.exe" />
</component>
<component Id="cmpC" Guid="*">
<file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe" />
</component>
</directory>
</fragment>
I am trying to find the file elements that have the Source attribute ending with 'BBB.exe' and replace its Id attribute with another value, e.g. with filNEW. In my example the Id attribute value 'filB' should be changed to 'filNEW'. So, my XSLT is defined the following way:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/fragment/directory/component/file[substring(#Source, string-length(#Source) - string-length('BBB.exe') + 1) = 'BBB.exe']">
<xsl:attribute name="Id">filNEW</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
However, instead of updating only the Id attribute of the file element of the second component element, the result has the whole file element removed for the second component and has the component element's Id attribute value replaced with the new filNEW value. The current result.
<?xml version="1.0" encoding="UTF-8"?>
<fragment>
<directory Id="dirABC" Name="ABC">
<component Guid="*" Id="cmpA">
<file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe"/>
</component>
<component Guid="*" Id="filNEW"/>
<component Guid="*" Id="cmpC">
<file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe"/>
</component>
</directory>
</fragment>
Whereas, I am trying to get this result:
<?xml version="1.0" encoding="UTF-8"?>
<fragment>
<directory Id="dirABC" Name="ABC">
<component Guid="*" Id="cmpA">
<file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe"/>
</component>
<component Id="cmpB" Guid="*">
<file Id="filNEW" KeyPath="yes" Source="SourceRootDir\BBB.exe" />
</component>
<component Guid="*" Id="cmpC">
<file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe"/>
</component>
</directory>
</fragment>
What am I doing wrong in the XSLT?
You are matching on the file element and then generating an attribute. If you just want to replace the value of the #Id attribute, then change your match expression to match on that #Id by adding /#Id after the predicate on the file:
<xsl:template match="/fragment/directory/component/file[substring(#Source, string-length(#Source) - string-length('BBB.exe') + 1) = 'BBB.exe']/#Id">
<xsl:attribute name="Id">filNEW</xsl:attribute>
</xsl:template>
I have the following (default) markup for my WiX installer project:
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='Acme' Name='Acme'>
<Directory Id='INSTALLDIR' Name='Foobar 1.0'>
<Component Id='MainExecutable' Guid='*'>
<File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1'
Source='FoobarAppl10.exe' KeyPath='yes'>
<Shortcut Id="startmenuFoobar10" Directory="ProgramMenuDir"
Name="Foobar 1.0" WorkingDirectory='INSTALLDIR'
Icon="Foobar10.exe" IconIndex="0" Advertise="yes" />
<Shortcut Id="desktopFoobar10" Directory="DesktopFolder"
Name="Foobar 1.0" WorkingDirectory='INSTALLDIR'
Icon="Foobar10.exe" IconIndex="0" Advertise="yes" />
</File>
</Component>
<Component Id='HelperLibrary' Guid='*'>
<File Id='HelperDLL' Name='Helper.dll' DiskId='1'
Source='Helper.dll' KeyPath='yes' />
</Component>
<Component Id='Manual' Guid='*'>
<File Id='Manual' Name='Manual.pdf' DiskId='1'
Source='Manual.pdf' KeyPath='yes'>
<Shortcut Id="startmenuManual" Directory="ProgramMenuDir"
Name="Instruction Manual" Advertise="yes" />
</File>
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="Foobar 1.0">
<Component Id="ProgramMenuDir" Guid="*">
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]'
Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
It compiles into the following MSI:
I'm wondering, can I add "Create desktop shortcuts" option to that installation tree so that users could select or remove it?
You just need to move the Shortcut elements into their own component(s), and add those to a new Feature.
This guide does it that way: How To: Create a Shortcut on the Start Menu
How to create a sub folder in installation folder(which in my case is named WWU)? I am creating an installation folder named WWU in Program Files, I want to create a sub folder named image inside WWU folder which will contain some necessary images files. I tried doing so using below code but I am unable to get folder being created.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{AADE647C-36C5-48A7-A88F-5AB8D6BAE7FE}" Name="WWU 1.0" Language="1033" Version="1.0.0.0" Manufacturer="Aricent Group" UpgradeCode="f89a1900-bdb0-4fec-a035-e69ae882716b">
<Package Id="*" Keywords="Installer" Description="Aricent's WWU 1.0 Installer" Comments="WWU is a registered trademark of Aricent Group." Manufacturer="Aricent Group" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<UIRef Id="WixUI_Minimal"/>
<WixVariable Id="WixUILicenseRtf" Value="$(var.WWU_UI.TargetDir)License.rtf"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id= "1" Cabinet="WWU.cab" EmbedCab="yes"/>
<Feature Id="Complete" Title="WWU`_Installer" Description="The complete package." Display="expand" ConfigurableDirectory="INSTALLFOLDER" Level="1">
<ComponentGroupRef Id="ProductComponents"/>
<ComponentGroupRef Id="Shortcuts"/>
</Feature>
<Feature Id="ImagePack" Title="Images" Level="1">
<ComponentGroupRef Id="ImageFiles"/>
</Feature>
</Product>
<Fragment>
<UI>
<Dialog Id="UserRegistrationDlg" Width="360" Height="250" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="NameLabel" Type="Text" X="45" Y="70" Width="100" Height="15" TabSkip="no" Text="User Name:"/>
<Control Id="NameEdit" Type="Text" X="45" Y="80" Width="220" Height="18" Property="USERNAME" Text="{80}" />
<Control Id="OrganizationalLabel" Type="Text" X="45" Y="110" Width="100" Height="15" TabSkip="no" Text="Organization:"/>
</Dialog>
</UI>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WWU" />
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="WWU 1.0" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
<Directory Id="ImageFolder" Name="image"/>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="MainExecutable" Guid="{434D54CC-D875-4B45-8125-CCCB8119A053}">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<File Id="WWUEXE" Name="WWU_UI.exe" Source="$(var.WWU_UI.TargetDir)WWU_UI.exe" KeyPath="yes">
<Shortcut Id="startmenuWWU" Directory="ProgramMenuDir" Name="WWU Tutorial 1.0" WorkingDirectory="IINSTALLDIR" Icon="WWU_UI.exe" Advertise="yes"/>
<Shortcut Id="desktopWWU" Directory="DesktopFolder" Name="WWU Tutorial 1.0" WorkingDirectory="IINSTALLDIR" Icon="WWU_UI.exe" Advertise="yes"/>
</File>
</Component>
<Component Id="SQLiteInterop" Guid="{7DBF7C38-3001-403F-911E-AF3C318F6219}">
<File Id="Interopdll" Name="SQLite.Interop.dll" Source="$(var.WWU_UI.TargetDir)x86\SQLite.Interop.dll" />
</Component>
<Component Id="SQLitedll" Guid="{DB1FB7CC-6D89-478B-9276-8F4F987027AC}" >
<File Id="SQLite" Name="System.Data.SQLite.dll" Source="$(var.WWU_UI.TargetDir)System.Data.SQLite.dll" />
</Component>
<Component Id="SQLiteLinqdll" Guid="{C65A7DD8-6F1A-4E02-86B2-2B2EDFFDD684}" >
<File Id="SQLiteLinq" Name="System.Data.SQLite.Linq.dll" Source="$(var.WWU_UI.TargetDir)System.Data.SQLite.Linq.dll" />
</Component>
<Component Id="Log4net" Guid="{5266C74E-D7F8-4091-90C2-B661A63B7909}" >
<File Id="Log4netdll" Name="log4net.dll" Source="$(var.WWU_UI.TargetDir)log4net.dll" />
</Component>
</ComponentGroup>
<ComponentGroup Id="Shortcuts" Directory="ProgramMenuDir">
<Component Id="ProgramMenuShortcut">
<RemoveFolder Id="ProgramMenuDir" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="" KeyPath="yes" />
</Component>
</ComponentGroup>
<!-- image files for image folder -->
<ComponentGroup Id="ImageFiles" Directory="ImageFolder">
<Component Id="Asfo" Guid="{B8031331-076F-4C75-B231-3EBCBBD8D29C}">
<File Id="Asfoimg" Name="0sf0.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\0sfo.ico" />
</Component>
<Component Id="Asfob" Guid="{D0D78785-3CFC-49C7-9470-90250034D331}">
<File Id="Asfobimg" Name="0sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\0sfob.ico" />
</Component>
<Component Id="Aufo" Guid="{6912A60F-F612-4AB8-B530-A0EA71AF8587}">
<File Id="Aufoimg" Name="0ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\0ufo.ico" />
</Component>
<Component Id="Aufob" Guid="{AD38A28F-3518-4AA4-B169-EC5077844E83}">
<File Id="Aufobimg" Name="0ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\0ufob.ico" />
</Component>
<Component Id="Bsfo" Guid="{D9A2BD2E-70C2-47DE-8B20-501A9D77A3CD}">
<File Id="Bsfoimg" Name="1sfo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\1sfo.ico" />
</Component>
<Component Id="Bsfob" Guid="{AC063280-4698-4605-B74C-471DEAD9D595}">
<File Id="Bsfobimg" Name="1sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\1sfob.ico" />
</Component>
<Component Id="Bufo" Guid="{0D840A42-3119-4283-9220-BCD722FA4D31}">
<File Id="Bufoimg" Name="1ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\1ufo.ico" />
</Component>
<Component Id="Bufob" Guid="{A8425CC9-5787-419D-8D37-8B6F16726C84}">
<File Id="Bufobimg" Name="1ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\1ufob.ico" />
</Component>
<Component Id="Csfo" Guid="{CBB6870F-3FBA-4ADC-B508-D865A8642C19}">
<File Id="Csfoimg" Name="2sfo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\2sfo.ico" />
</Component>
<Component Id="Csfob" Guid="{E0EBE823-11EB-4054-A544-1F9859D06A00}">
<File Id="Csfobimg" Name="2sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\2sfob.ico" />
</Component>
<Component Id="Cufo" Guid="{E1870A35-B398-4B4A-AC1C-0A701A5188F8}">
<File Id="Cufoimg" Name="2ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\2ufo.ico" />
</Component>
<Component Id="Cufob" Guid="{3A6EA0AE-38C0-496C-B977-3342F3C6D8B8}">
<File Id="Cufobimg" Name="2ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\2ufob.ico" />
</Component>
<Component Id="Dsfo" Guid="{2D575CA7-96DA-40A1-B1EC-173F455E47C4}">
<File Id="Dsfoimg" Name="3sfo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\3sfo.ico" />
</Component>
<Component Id="Dsfob" Guid="{C08977BB-8FF7-459F-B3B3-8A9E75152EF5}">
<File Id="Dsfobimg" Name="3sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\3sfob.ico" />
</Component>
<Component Id="Dufo" Guid="{552B1B41-247D-490B-9433-B642CAD6A70A}">
<File Id="Dufoimg" Name="3ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\3ufo.ico" />
</Component>
<Component Id="Dufob" Guid="{3140C586-45C8-4496-BADD-3F55D9F2B751}">
<File Id="Dufobimg" Name="3ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\3ufob.ico" />
</Component>
<Component Id="Esfo" Guid="{311F89D5-5E53-4B45-87F7-B521ACC6D7C1}">
<File Id="Esfoimg" Name="4sfo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\4sfo.ico" />
</Component>
<Component Id="Esfob" Guid="{E9239C1D-3F5A-497B-92D4-0830E739A5E9}">
<File Id="Esfobimg" Name="4sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\4sfob.ico" />
</Component>
<Component Id="Eufo" Guid="{8A057476-D9B3-4033-9906-567377D97304}">
<File Id="Eufoimg" Name="4ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\4ufo.ico" />
</Component>
<Component Id="Eufob" Guid="{8CE17A52-19B1-4FB6-9D12-0B231E3DDE4D}">
<File Id="Eufobimg" Name="4ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\4ufob.ico" />
</Component>
<Component Id="Fsfo" Guid="{D0433C83-BCC5-41EB-8015-9D76E4457448}">
<File Id="Fsfoimg" Name="5sfo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\5sfo.ico" />
</Component>
<Component Id="Fsfob" Guid="{C65BD8E6-C9F1-4A75-9A23-3A6DB35B4BFC}">
<File Id="Fsfobimg" Name="5sfob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\5sfob.ico" />
</Component>
<Component Id="Fufo" Guid="{4F9D5939-7011-4D99-A65B-3F0A2130622B}">
<File Id="Fufoimg" Name="5ufo.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\5ufo.ico" />
</Component>
<Component Id="Fufob" Guid="{90D7B520-4A37-42AC-AB62-F5485A89FCC9}">
<File Id="Fufobimg" Name="5ufob.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\5ufob.ico" />
</Component>
<Component Id="Ari_WWU" Guid="{086B969B-BAA2-4DFA-B699-F56FF885AB26}">
<File Id="Ari_WWUimg" Name="Ari_WWU.ico" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\Ari_WWU.ico" />
</Component>
<Component Id="auto" Guid="{9625F82B-B206-40E6-9310-8D46563E20C6}">
<File Id="auto" Name="auto.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\auto.png" />
</Component>
<Component Id="info" Guid="{DDCBB410-77DD-49C9-9372-98DD2747121E}">
<File Id="infoimg" Name="info.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\info.png" />
</Component>
<Component Id="manual" Guid="{4F8768A8-E44C-4781-9680-95CAC631CFB7}">
<File Id="manualimg" Name="manual.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\manual.png" />
</Component>
<Component Id="off" Guid="{702551D4-34DD-4B1B-B4F6-614DEFA4542A}">
<File Id="offimg" Name="off.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\off.png" />
</Component>
<Component Id="on" Guid="{7682A68D-712B-4F70-9EE2-FB4F0E04947D}">
<File Id="onimg" Name="on.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\on.png" />
</Component>
<Component Id="refresh" Guid="{9815CA13-659C-466D-B759-5EF557069D1B}">
<File Id="refreshimg" Name="refresh.png" KeyPath="yes" Source="$(var.WWU_UI.TargetDir)image\refresh.png" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<Icon Id="WWU_UI.exe" SourceFile="$(var.WWU_UI.TargetDir)WWU_UI.exe"/>
</Fragment>
</Wix>
You should nest the <Directory Id="ImageFolder"> under <Directory Id="INSTALLFOLDER">, like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WWU">
<Directory Id="ImageFolder" Name="image"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="WWU 1.0" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
Note also that if there's no component in that folder, the empty directory won't be created. In order for this to happen, you'll have to author a component with <CreateFolder> element in it.
This is what you do.
Nest the subfolder underneath INSTALLFOLDER as stated by Yan.
Create the Feature Component with the CreateFolder bit inside
Example code:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixInstallerExample" >
<Directory Id="test" Name="AnotherDirectory">
<Component Id="test" Guid="e29f1a9e-3ede-40d6-aba0-bfe451002ee3"
SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="no" Win64="no" Location="either">
<CreateFolder/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="test" Title="testfolder" Level="1">
<ComponentRef Id="test"/>
</Feature>
</Fragment>