1

I already successfully created an MSI for PyCharm because the installer is not working properly in silent mode. So I had my first successful experience with WiX.

Now, I got a folder to install from our developers. This program should go to "C:\ProgramFiles\Folder A\Folder B" because later there will be another package that goes to "C:\ProgramFiles\Folder A\Folder C"

So, here's what I got (part of it):

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
        <Directory Id="APPLICATIONROOTDIRECTORY" Name="Folder A"/>
        <Directory Id="APPLICATIONSUBDIRECTORY" Name="Folder B"/>
    </Directory>

    <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="Program B"/>
    </Directory>
</Directory>

I am trying now to create the shortcut

<Shortcut Id="ApplicationStartMenuShortcut" Name="Program B" Target="[APPLICATIONSUBDIRECTORY]\Program B.exe" Icon="ProductIcon" WorkingDirectory="APPLICATIONSUBDIRECTORY"/>

So, my intention was that APPLICATIONSUBDIRECTORY = "C:\ProgramFiles\Folder A\Folder B" but it's going to be "C:\ProgramFiles\Folder B"

I found this: Setting Wix shortcut with environment variable workingdirectory

But I would rather not use additional properties if there's already a directory structure.

Leaving away this:

<Directory Id="APPLICATIONSUBDIRECTORY" Name="Folder B"/>

and using APPLICATIONROOTDIRECTORY would work but I need a second layer of folders.

The Target attribute does not like this as well. Using (a combination of variables)

Target="[APPLICATIONROOTDIRECTORY]\[APPLICATIONSUBDIRECTORY]\Program B.exe"

does not work but

Target="[APPLICATIONROOTDIRECTORY]\Folder B\Program B.exe"

does.

As I am new to WiX I am still struggling to define directories. The first 2 Directory Ids are joined but the 3rd one doesn't.

<Directory Id="ProgramFilesFolder">
    <Directory Id="APPLICATIONROOTDIRECTORY" Name="Folder A"/>
    <Directory Id="APPLICATIONSUBDIRECTORY" Name="Folder B"/>
</Directory>

This is my batch file:

@echo off
SET WIXPATH=C:\Program Files (x86)\WiX Toolset v3.11\bin
SET COMPONENTGROUP=MyCompGroup
SET FILEFOLDER=Files
SET FILELIST=FileList
SET MAINFILE=Main
SET MSINAME=Program B.msi

if exist FileList.wxs del FileList.wxs
if exist *.wixobj del *.wixobj
if exist *.wixpdb del *.wixpdb
if exist *.msi del *.msi
if exist *.cab del *.cab
pause

"%wixpath%\heat.exe" dir ".\%FILEFOLDER%" -cg %COMPONENTGROUP% -dr APPLICATIONROOTDIRECTORY -out %FILELIST%.wxs -gg -ke -srd -sfrag -template fragment

"%wixpath%\candle.exe" -arch x86 %MAINFILE%.wxs %FILELIST%.wxs

"%wixpath%\light.exe" -b %FILEFOLDER% -out "%MSINAME%" %MAINFILE%.wixobj %FILELIST%.wixobj

And that's the directory structure to "capture":

/--Files
/----Program B
/------File1
/------File2

etc.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Fabian S.
  • 23
  • 5

3 Answers3

1

Glitch in Directory Structure

It looks like there is an error in your Directory hierarchy. Maybe try to change it to look like this as a first step:

<Directory Id="TARGETDIR" Name="SourceDir">

  <Directory Id="ProgramFilesFolder">
    <Directory Id="APPLICATIONROOTDIRECTORY" Name="Folder A">
      <Directory Id="APPLICATIONSUBDIRECTORY" Name="Folder B" />
    </Directory>
  </Directory>

  <Directory Id="ProgramMenuFolder">
    <Directory Id="ApplicationProgramsFolder" Name="Program B" />
  </Directory>

</Directory>

Are you using Visual Studio? Try going Edit => Advanced => Format Document when you have your WiX source file open. See what the indentation looks like. Your sub-folders should be indented as shown above. If they don't indent, look at the /> entries. Only add these if you indicate that there are no further sub-folders.

Adding Your Shortcut

As to your shortcut. Here is how you should be able to add an advertised shortcut to a file you install:

<Shortcut Id="mysc" Advertise="yes" Directory="ApplicationProgramsFolder" 
          Name="My Shortcut" Description="My Shorcut Description" />

This Shortcut element should be added to the component that installs the file in question, for example like this:

<Component Id="NOTEPAD.EXE" Feature="ProductFeature">

   <File Source="MyReleaseFiles\NOTEPAD.EXE" />

   <Shortcut Id="mysc" Advertise="yes" Directory="ApplicationProgramsFolder" 
             Name="My Shortcut" Description="My Shorcut Description" />

   <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"
                 Directory="ApplicationProgramsFolder"/>

</Component>

Visual Studio

You can install the Visual Studio 2017 Community Edition for free - and I recommend this way to make WiX MSIs. You get some more help from the tool to avoid errors such as the issue with your Directory hierarchy.

I wrote a short answer on how to create a minimal "Hello World" style WiX MSI using Visual Studio: WiX installer msi not installing the Winform app created with Visual Studio 2017.

You might want to reinstall the latest WiX version and the Visual Studio extensions (2017) if you install Visual Studio to ensure that the WiX project types and extensions are available.

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • Thanks for your reply. I'm using Visual Studio Code and the current WiX 3.11. That's why I flagged my question as "wix3.11". With the directory you were right: I need to be careful with the terminating "/>". I got it to work. As for the shortcut, it was working. The only problem was the path because the shortcut element does not accept a combination of variables. Now with the directory structure working I was able to use the new variable (containing the whole path) within the shortcut element. – Fabian S. Jan 25 '18 at 09:34
0

Still learning how this forum works :-) To post markup I need to use "answer" instead of "comment", right?

This is how it works like @Stein Åsmul wrote:

I split every directory element into <Directory> and </Directory> instead of just <Directory />.
I know it's not necessary for the "last" one but just to make it clear for me next time I look at that code :-)

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
        <Directory Id="APPLICATIONROOTDIRECTORY" Name="Folder A">
            <Directory Id="APPLICATIONSUBDIRECTORY" Name="Folder B">
            </Directory>
        </Directory>
    </Directory>

    <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="Program B">
        </Directory>
    </Directory>
</Directory>

The shortcut part works like this:

<DirectoryRef Id="ApplicationProgramsFolder">
    <Component Id="ApplicationShortcut" Guid="*PUT-IN-GUID*">
        <Shortcut Id="ApplicationStartMenuShortcut" Name="Program B" Target="[APPLICATIONSUBDIRECTORY]\Program B.exe" Icon="ProductIcon" WorkingDirectory="APPLICATIONSUBDIRECTORY"/>
        <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
        <RegistryValue Root="HKCU" Key="Software\[blabla]\Program B" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
    </Component>
</DirectoryRef>

It's not perfect but way better than copying the whole crap by batch file... It would be even better if our developers would use WiX instead of giving me just binaries to deploy :-)

Fabian S.
  • 23
  • 5
0

As another workaround I was able to create a new property yesterday using a custom action. It is not upper case on purpose.

<SetProperty Id="ApplicationFullDirectory" Value="[APPLICATIONROOTDIRECTORY]Folder B" After="CostInitialize" />

This allowed me to use the new variable/property "ApplicationFullDirectory" in the shortcut element.

<Shortcut Id="ApplicationStartMenuShortcut" Name="Program B" Target="[ApplicationFullDirectory]\Program B.exe" Icon="ProductIcon" WorkingDirectory="ApplicationFullDirectory"/>

But still learning :-)

Fabian S.
  • 23
  • 5