How to create a multi-level subfolder in Start menu using WiX
Asked Answered
C

1

13

How do I create sub folders (several levels deep) in the Windows Start menu, using WiX?

Currently I am able to put my shortcut in the Start menu, but only in a folder immediately under Programs (Start / Programs / MyFolder), but I want to nest my shortcut deeper (Start / Programs / MyPlatform / MyProduct / etc.). I tried different combinations, but alas.

<DirectoryRef Id="StartMenuMyProduct">
    <Component Id="ApplicationShortcut" Guid="{PUT-SOME-GUID-HERE}">
        <Shortcut Id="ApplicationStartMenuShortcut"
                  Name="Configure My Product"
                  Description="Add or remove this and that"
                  Target="[MYPRODUCTDIR]ConfigureMyProduct.exe"
                  WorkingDirectory="MYPRODUCTDIR"/>
        <RemoveFolder Id="StartMenuMyProduct"
                      On="uninstall"/>
        <RemoveFolder Id="StartMenuMyPlatform"
                      On="uninstall"/>
        <RegistryValue Root="HKCU"
                       Key="SOFTWARE\MyCompany\MyPlatform\My Product"
                       Name="Installed"
                       Type="integer"
                       Value="1"
                       KeyPath="yes"/>
    </Component>
</DirectoryRef>

<!-- Shortcut to the configuration utility in the Windows Start menu -->
<Directory Id="ProgramMenuFolder">
    <!--<Directory Id="StartMenuMyPlatform" Name="MyPlatform">-->
      <Directory Id="StartMenuMyProduct" Name="My Product" />
    <!--</Directory>-->
</Directory>
Chastitychasuble answered 22/1, 2009 at 20:24 Comment(3)
Nice question, haven't tried that ...Chutzpah
BTW, your GUID (which you shouldn't have posted if you care about it staying a "globally unique ID" ;-)) looks hand-crafted. You should just use uuidgen.exe which comes with visual studio, or some other guid generator.Bolen
Hehe, thanks, corrected. Yes, i know, i copied from my source code and just added a bunch of zeros before i posted here!Chastitychasuble
B
22

What makes things interesting is that MSI demands a registry value to be created as a way to detect whether the component has been installed. If we prefer to create only one such registry value for all shortcuts, then we'll have to put all our shortcuts in a single component.

Fortunately it is possible to create components which span multiple target directories by making use of the Directory attribute on the Shortcut element.

   <!-- shortcuts to applications in the start menu -->
   <DirectoryRef Id="ProgramMenuProductFolder">
      <Component Id="ProgramMenuShortcutsComponent" Guid="PUT-GUID-HERE">
         <!-- create folders -->
         <CreateFolder Directory="ProgramMenuVendorFolder" />
         <CreateFolder Directory="ProgramMenuProductFolder" />
         <CreateFolder Directory="ProgramMenuSubFolder" />
         <!-- remove folder -->
         <RemoveFolder Id="RemoveProgramMenuVendorFolder"
            Directory="ProgramMenuVendorFolder"
            On="uninstall" />
         <RemoveFolder Id="RemoveProgramMenuProductFolder"
            Directory="ProgramMenuProductFolder"
            On="uninstall" />
         <RemoveFolder Id="RemoveProgramMenuProductSubFolder"
            Directory="ProgramMenuProductSubFolder"
            On="uninstall" />
         <!-- main shortcut -->
         <Shortcut
            Id="MainShortcut"
            Name="My Product"
            Target="[SomeInstalledFolder]app1.exe" />
         <!-- shortcut in subfolder -->
         <Shortcut
            Id="SubFolderShortcut"             
            Name="mySubFolderShortcut"
            Target="[SomeInstalledFolder]app2.exe"
            Directory="ProgramMenuProductSubFolder" />
         <!--
            RegistryValue whichs serves as KeyPath
         -->
         <RegistryValue
            Root="HKCU"
            Key="Software\MyVendor\MyProduct"
            Name="InstalledStartMenuShortcuts"
            Type="integer"
            Value="1" />
      </Component>
   </DirectoryRef>

   <!-- shortcut directories -->
   <Directory Id="ProgramMenuFolder">
      <Directory Id="ProgramMenuVendorFolder" Name="MyVendor">
         <Directory Id="ProgramMenuProductFolder" Name="MyProduct">
            <Directory Id="ProgramMenuProductSubFolder" Name="MySubFolder" />
         </Directory>
      </Directory>
   </Directory>
Bolen answered 22/1, 2009 at 23:8 Comment(8)
Minor clarification, it's not WiX that requires the registry value, it's MSI. We're just living by the lame requirements.Gaylordgaylussac
Hate to bump such an old thread, but I'm using this component syntax to make my shortcut entries, and they are not getting cleaned up properly when I install a newer version using major upgrade as shown here: blogs.technet.com/b/alexshev/archive/2008/02/15/…. So I first install say 1.0.1.0, that will be in Start Menu\Programs\Manufacturer\Product 1.0.1.0 and if I install 1.0.2.0 later, it will upgrade 1.0.1.0 but it will create a new entry titled Start Menu\Programs\Manufacturer\Product 1.0.2.0. How do I get it to clean up properly?Shalandashale
Nevermind, took out the naming in the Product shortcut dir (now calling it Start Menu\Programs\Manufacturer\Product instead of Start Menu\Programs\Manufacturer\Product version) and seems to work now.Shalandashale
I have one question regarding this old post: what's the purpose of those CreateFolder elements? Because in the second part, the directory elements, the folder structure is already defined and hence during the installation those directories will be created if they are not present. So what's the purpose of those CreateFolder ? The truth is I never understood it.Yingyingkow
@tete: The CreateFolder elements are indeed not necessary, I'll remove them from my answer. The RemoveFolder elements are still needed, removing them triggers ICE64.Bolen
I followed your example to create a shortcut to MyProduct.exe. The installer kept giving warning 1909. Couldn not create [s]. Verify that the destination folder exists... The first short didn't get created. However the second shortcut was created successfully. Adding CreateFolder to the Component didn't solve it.Hennebery
@CandyChiu: I've rolled back my last edit, apparently the CreateFolder elements are typically required after all. Note that I use the Directory= attribute to create specific folders, instead of the default behavior which is to create the parent folder of the component.Bolen
@RobMensching, I am having an issue similar to Jack where I'm doing a major upgrade of my product, but I'm actually changing the product name so the old start menu folder is not getting deleted. I end up with two entries, one with the old name and one with the new. How do I eliminate the old entry?Nellenelli

© 2022 - 2024 — McMap. All rights reserved.