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.
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 got the following file in WiX:
<Component Id='MainExecutable' Guid='91C8C2C0-59AF-4BDD-A78D-C4369DD4CD81'>
<File Id='FoobarEXE' Name='FoobarAppl10.exe' Source='FoobarAppl10.exe' KeyPath='yes'>
</File>
</Component>
<Component Id="ProgramMenuDir" Guid="D3B0871E-A86D-4692-B419-AE2A2A578648">
<RegistryValue Root='HKCR' Key='conversationwindowaction\shell\open\command' Type='string' Value='"[absolute path to exe]" "%1"' KeyPath='yes' />
</Component>
I want [absolute path to exe] be the string to the path of FoobarEXE, how can I do this?
<Component Id="ProgramMenuDir" Guid="D3B0871E-A86D-4692-B419-AE2A2A578648">
<RegistryValue Root='HKCR' Key='conversationwindowaction\shell\open\command' Type='string' Value='"[#FoobarEXE]" "%1"' KeyPath='yes' />
</Component>
You need to enclose the file id in [#fileid] see example above.
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>
I've been working on creating multiple instances for my install and this is the code I have so far NOTE: Obvious data has been removed. I get the UI come up and I get all the way up to the Install phase and just when it hits the Progress Dialog I get an error message.
I know it's not my msiexec version or the service as I have checked everything. Can anyone let me know exactly what is causing this issue?
<!--Multi-instance-->
<InstanceTransforms Property="INSTANCEID">
<Instance Id="Inst1" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductInst1"/>
<Instance Id="Inst1Stage" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductInst1Stage"/>
<Instance Id="Inst3" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductInst3"/>
<Instance Id="Inst4" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductInst4"/>
<Instance Id="Other" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductOther"/>
<Instance Id="Other2" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductOther2"/>
<Instance Id="Other3" Inst1PProductductCode="**GUID**" Inst1PProductductName="Inst1PProductductOther3"/>
</InstanceTransforms>
<!--Registering Multiple Instances-->
<Property Id="Inst1INSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Inst1Inst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Inst1" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="Inst1STAGEINSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Inst1StageInst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Inst1Stage" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="Inst3INSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Inst3Inst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Inst3" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="Inst4INSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Inst4Inst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Inst4" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="OTHERINSTALLEDInst1PProductductCODE">
<RegistrySearch Id="OtherInst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Other" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="OTHER2INSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Other2Inst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Other2" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<Property Id="OTHER3INSTALLEDInst1PProductductCODE">
<RegistrySearch Id="Other3Inst1PProductductCodeLookUp" Key="$(var.RegKeyDir)\Other3" Name="**GUID**" Productot="HKLM" Type="raw"/>
</Property>
<!--Installation Files-->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="PProductgramFilesFolder" Name="PProductgramFiles">
<Directory Id="INSTALLDIR" Name="Inst1PProductduct">
<Directory Id="Inst1PProductductWEB"> <!--Name="Inst1PProductduct(Inst1) Web"-->
<!--RegCompCode-->
<!--IISWebPoolCode-->
<Component Id="IISWebPool" Guid="$(var.IISWebPoolCode)" Win64="no" MultiInstance="yes" Permanent="yes">
<iis:WebAppPool Id="Inst1PProductduct" Name="Inst1PProductductAppPool" ManagedRuntimeVersion="[NET_VER]" IdleTimeout="0" RecycleMinutes="0" ManagedPipelineMode="integrated"/>
<CreateFolder />
</Component>
<!--IISWebRegCode-->
<Component Id="IISWebReg" Guid="$(var.IISWebRegCode)" KeyPath="yes" MultiInstance="yes">
<iis:WebVirtualDir Id="ProductVirtualDir" Alias="[SHORTCUT]" Directory="Inst1PProductductWEB" WebSite="DefaultWebSite" >
<iis:WebApplication Id="ProductWebApp" Name="[SHORTCUT]" WebAppPool="Inst1PProductduct" />
<iis:WebDirPProductperties Id="ProductWebDir" AnonymousAccess="yes" WindowsAuthentication="yes" />
</iis:WebVirtualDir>
<CreateFolder />
</Component>
<!--WebDataFilesCode-->
<Component Id="WebDataFiles" Guid="$(var.WebDataFilesCode)" MultiInstance="yes">
<File Id="clientaccesspolicy.xml" Source="$(var.Inst1PProductductWebFiles)\clientaccesspolicy.xml" Vital="yes" DiskId="1"/>
<File Id="Default.aspx" Source="$(var.Inst1PProductductWebFiles)\Default.aspx" Vital="yes" DiskId="1"/>
<File Id="Global.asax" Source="$(var.Inst1PProductductWebFiles)\Global.asax" Vital="yes" DiskId="1"/>
<File Id="Global.asax.cs" Source="$(var.Inst1PProductductWebFiles)\Global.asax.cs" Vital="yes" DiskId="1"/>
<File Id="Help.aspx" Source="$(var.Inst1PProductductWebFiles)\Help.aspx" Vital="yes" DiskId="1"/>
<File Id="Help.aspx.cs" Source="$(var.Inst1PProductductWebFiles)\Help.aspx.cs" Vital="yes" DiskId="1"/>
<File Id="Print.aspx" Source="$(var.Inst1PProductductWebFiles)\Print.aspx" Vital="yes" DiskId="1"/>
<File Id="Report.aspx" Source="$(var.Inst1PProductductWebFiles)\Report.aspx" Vital="yes" DiskId="1"/>
<File Id="Inst1PProductductHelp.aspx" Source="$(var.Inst1PProductductWebFiles)\Inst1PProductductHelp.aspx" Vital="yes" DiskId="1"/>
<File Id="Silverlight.js" Source="$(var.Inst1PProductductWebFiles)\Silverlight.js" Vital="yes" DiskId="1"/>
<File Id="WcfPortal.svc" Source="$(var.Inst1PProductductWebFiles)\WcfPortal.svc" Vital="yes" DiskId="1"/>
<File Id="WcfSecurePortal.svc" Source="$(var.Inst1PProductductWebFiles)\WcfSecurePortal.svc" Vital="yes" DiskId="1"/>
<File Id="Web.sample.config" Source="$(var.Inst1PProductductWebFiles)\Web.sample.config" Vital="yes" DiskId="1"/>
<File Id="WpfWcfPortal.svc" Source="$(var.Inst1PProductductWebFiles)\WpfWcfPortal.svc" Vital="yes" DiskId="1"/>
<File Id="Web.config" KeyPath="yes" Source="$(var.Inst1PProductductWebFiles)\Web.config" Vital="yes" />
<util:XmlFile Id="SetConn" Action="setValue" ElementPath="/configuration/connectionStrings/add[\[]#name='Inst1PProductductConnectionString'[\]]/#connectionString"
Value="Data Source=[SERVERNAME];Initial Catalog=[DBNAME];Password="encrypted:kUrWr7n47L3akvAu89Evew==";User ID=Productster;"
File="[#Web.config]" SelectionLanguage="XPath" Sequence="1" />
</Component>
<!--RegisterFolderCode-->
<!--<Component Id="RegisterFolder" Guid="$(var.RegisterFolderCode)">
<RegistryValue Id="AppAlias" Name="AppAlias" Productot="HKLM" Key="SOFTWARE\Inst1PProductduct\Inst1PProductductWeb(Inst1)" Type='string' Value="[SHORTCUT]" KeyPath='yes'/>
<RegistryValue Id="VirtualDir" Name='VirtualDir' Productot='HKLM' Key='SOFTWARE\Inst1PProductduct\Inst1PProductductWeb(Inst1)' Type='string' Value='[SHORTCUT]'/>
</Component>-->
<!--Registering Individual Instances-->
<Component Id="Registry_Inst1" Guid="$(var.RegInst1Comp)">
<Condition><![CDATA[INSTANCEID = "Inst1"]]></Condition>
<RegistryKey Productot="HKLM" Key="$(var.RegKeyDir)\[INSTANCEID]" >
<RegistryValue Id="Presence_Inst1" Action="write" Name="Inst1Inst1PProductductCode" Value="[Inst1PProductductCode]" Type="string" KeyPath="yes" />
</RegistryKey>
</Component>
<Component Id="Registry_Inst1Stage" Guid="$(var.RegInst1StageComp)">
<Condition><![CDATA[INSTANCEID = "Inst1Stage"]]></Condition>
<RegistryKey Productot="HKLM" Key="$(var.RegKeyDir)\[INSTANCEID]" >
<RegistryValue Id="Presence_Inst1Stage" Action="write" Name="Inst1StageInst1PProductductCode" Value="[Inst1PProductductCode]" Type="string" KeyPath="yes" />
</RegistryKey>
</Component>
<Component Id="Registry_Inst3" Guid="$(var.RegInst3Comp)">
<Condition><![CDATA[INSTANCEID = "Inst3"]]></Condition>
<RegistryKey Productot="HKLM" Key="$(var.RegKeyDir)\[INSTANCEID]" >
<RegistryValue Id="Presence_Inst3" Action="write" Name="Inst3Inst1PProductductCode" Value="[Inst1PProductductCode]" Type="string" KeyPath="yes" />
</RegistryKey>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<!--Create web applicaton under Default Website-->
<iis:WebSite Id="DefaultWebSite" Description="[SHORTCUT]" Directory="Inst1PProductductWEB">
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<Feature Id="$(var.Feature)Install"
Title="$(var.InstallName) Installer"
Description="$(var.InstallName) Setup Wizard"
Display="expand"
Level="1"
ConfigurableDirectory="Inst1PProductductWEB">
<Feature Id="$(var.Feature)" Title="$(var.InstallName)" Description="$(var.InstallName)" Level="1">
<ComponentRef Id="IISWebPool" />
<ComponentRef Id="IISWebReg" />
<ComponentRef Id="WebDataFiles" />
<ComponentRef Id="BinFiles" />
<ComponentRef Id="ClientBinFiles" />
<ComponentRef Id="Registry_Inst1" />
<ComponentRef Id="Registry_Inst1Stage" />
<ComponentRef Id="Registry_Inst3" />
</Feature>
</Feature>
<!--UI-->
<UI Id="Installer_UI">
<UIRef Id="WixUI_Mondo"/>
<Property Id="WIXUI_INSTALLER" Value="TARGETDIR"/>
<DialogRef Id="InstallerUIDlg"/>
<DialogRef Id="InstallDlg"/>
<DialogRef Id="InstallPProductgressDlg"/>
<Publish Dialog="ExitDialog" ContProductl="Finish" Event="EndDialog" Value="Return" Order="999"></Publish>
<Publish Dialog="LicenseAgreementDlg" ContProductl="Next" Event="NewDialog" Value="InstallerUIDlg" Order="2">LicenseAccepted = "1"</Publish>
<Publish Dialog="SetupTypeDlg" ContProductl="Back" Event="NewDialog" Value="InstallerUIDlg" Order="2">1</Publish>
<Publish Dialog="PProductgressDlg" ContProductl="Next" Event="NewDialog" Value="InstallerUIDlg" Order="2">1</Publish>
</UI>
<UIRef Id="WixUI_Common"/>
<!--Custom Actions-->
<CustomAction Id="SetInst1PProductductName" Property="Inst1PProductductName" Value="[[Inst1PProductductNameProperty][INSTANCEID]]" />
<CustomAction Id="SetInstanceDirectory" Property="Inst1PProductductWEB" Value="[INSTALLDIR][INSTANCEID]\"/>
<CustomAction Id="SetTransforms" Property="TRANSFORMS" Value="{:[INSTANCEID];}[TRANSFORMS]" />
<CustomAction Id="SetNewInstance" Property="MSINEWINSTANCE" Value="1" />
<CustomAction Id="SetInstance_Inst1" Property="INSTANCEID" Value="Inst1" />
<CustomAction Id="SetInstance_Inst1Stage" Property="INSTANCEID" Value="Inst1Stage" />
<CustomAction Id="SetInstance_Inst3" Property="INSTANCEID" Value="Inst3" />
<CustomAction Id="SetInstance_Inst4" Property="INSTANCEID" Value="Inst4" />
<CustomAction Id="SetInstance_Other" Property="INSTANCEID" Value="Other" />
<CustomAction Id="SetInstance_Other2" Property="INSTANCEID" Value="Other2" />
<CustomAction Id="SetInstance_Other3" Property="INSTANCEID" Value="Other3" />
<InstallExecuteSequence>
<Custom Action="SetInst1PProductductName" Before="ValidateInst1PProductductID" />
<Custom Action="SetInstanceDirectory" Before="CostFinalize"><![CDATA[Inst1PProductductWEB = ""]]></Custom>
<RemoveExistingInst1PProductducts Before="InstallInitialize" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="SetInstance_Inst1" Before="SetTransforms"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND Inst1INSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Inst1Stage" After="SetInstance_Inst1"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND Inst1STAGEINSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Inst3" After="SetInstance_Inst1Stage"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND Inst3INSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Inst4" After="SetInstance_Inst3"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND Inst4INSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Other" After="SetInstance_Inst4"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND OTHERINSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Other2" After="SetInstance_Other"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND OTHER2INSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetInstance_Other3" After="SetInstance_Other2"><![CDATA[ACTION = "INSTALL" AND INSTANCEID = "Default" AND OTHER3INSTALLEDInst1PProductductCODE = ""]]></Custom>
<Custom Action="SetTransforms" Before="ExecuteAction"><![CDATA[ACTION = "INSTALL"]]></Custom>
<Custom Action="SetNewInstance" Before="ExecuteAction"><![CDATA[ACTION = "INSTALL"]]></Custom>
</InstallUISequence>
My understanding is that you must set the TRANSFORMS and MSINEWINSTANCE values before the MSI package is launched. The MSI SDK shows it in the topic: Installing Multiple Instances with Instance Transforms. It is possible you could set MSINEWINSTANCE via a custom action as you are but I'm pretty certain that the TRANSFORMS property must be set before the MSI package is opened by the Windows Installer because the transform is applied as the MSI package is opened.
Basically, you need some sort of bootstrapper or documented command-line process to set these correctly. Multiple instance packages in the Windows Installer are challenging because of these types of issues.
I would try testing/troubleshooting from the command line first to eliminate the complexity of the UI.
You should always pass in your transform and always specify MSINEWINSTANCE=1 from the command line when installing an instance.
msiexec /i App.msi TRANSFORMS=:Inst1 MSINEWINSTANCE=1
msiexec /i App.msi TRANSFORMS=:Inst1Stage MSINEWINSTANCE=1
msiexec /x App.msi TRANSFORMS=:Inst1
msiexec /x App.msi TRANSFORMS=:Inst1Stage
I'm thinking if you can verify things are right via the command line, then you can confirm your issue is specific to the GUI and the CAs associated with setting your instance.