Adding files & folders is painful

Oct 3, 2009 at 5:31 PM

Thanks for this - it looks perfect. Now the only catch is manually adding ALL the content files, and then worrying that I'll forget to add new ones as the game evolves.

There must be a way to speed this up. What about compressing all the content files and DLLs into a single (or per component) archive and extracting it as a post install step. I guess I could do it on first run of the game, but it'd be great to set it up as part of the installer.

The other option I can think of is to write a little program that generates the Files.wxs file based on the directory structure of your game's deployment folder.

Any thoughts?

Coordinator
Oct 4, 2009 at 9:37 AM

Sure, there are several ways to make this easier or even to fully automate Files.wxs:

Your first idea won't work well with WiX. Windows Installer wants to know about all files it installs so it knows what to uninstall again and what to check when deploying updates. You could, theoretically, add a .zip file to each <Component /> and run a custom action (allows you to run arbitrary code) after the installer has finished copying files that extracts them, but this would increase the required free disk space, take longer and not cooperate well with Windows Installer (especially if you delete the .zip files afterwards, Windows Installer will assume your install is broken).

Your second idea is how people using WiX are actually doing it. There's a tool named "tallow" in the WiX distribution (in SharpDevelop, it's under SharpDevelop\bin\tools\wix or so) which will auto-generate Files.wxs from an existing directory structure. It's flexible enough to be used to batch files or NAnt/MSBuild scripts so you could manage a one-click update and recompile for your setup project.

SharpDevelop also has an Explorer-like editor for Files.wxs built in. This tutorial shows how to display it in the "Adding Files" section: http://community.sharpdevelop.net/blogs/mattward/archive/2007/01/08/CreatingAnInstallerWithSharpDevelop.aspx

 

Don't be surprised if those tools create one <Component /> per file - that's common practice because when you create an update installer, only whole <Component />s can be updated, not individual files therein. One <Component /> per file makes update creation easier - at the cost of some more work for the installer.

Oct 4, 2009 at 12:05 PM

Thank you, that is very helpful. I did try the Add Directory which at first made me go "Awesome!, it's recursive", but then I realised why you said "It's not exactly a time saver" - all the files are there, but since they each have their own Component, you still need to add every single one to your Feature(s).

I looked for Tallow, but it seems it's been replaced with a more powerful tool called Heat WiX 3.0. Time to look into generating my setup. Thanks Again.

Aranda

 

Oct 4, 2009 at 2:55 PM
Edited Oct 4, 2009 at 3:31 PM

For the benefit of other non-wix-gurus who come across this issue, here's how I managed to use heat.exe to generate the file list for my game:

1) I created a .bat file at the root of the Wix XNA template folder with the following contents:

 

"C:\Program Files\SharpDevelop\3.0\bin\Tools\Wix\heat.exe" dir "C:\Path\To\My\GameDir" -cg MyGameFilesGroup -gg -out ".\Source\MyGameFiles.wxs" -var var.GameDeployFolder

 

2) Added the generated MyGameFiles.wxs file to the setup project under the Source folder

3) Edited Setup.wxs and added <ComponentGroupRef Id="MyGameFilesGroup" /> to the list of Components in the default <Feature /> element

4) Edited the properties of the setup project (MyGame) in SharpDevelop (Preprocessing tab) and added a variable called GameDeployFolder with the value of C:\Path\To\My\GameDir.

 

I haven't properly tested all aspects of the resulting msi, but I'll be sure to post back here if there are any problems ;)

Thanks again Cygon for your help.

[EDIT] - Oh damn. I just noticed none of the files in MyGameFilesGroup were installed. Back to the drawing board.

[EDIT] Almost there. I Changed the bat file to this and now all my game files are installed but into a sub directory of "C:\program files\MyGame\":

"C:\Program Files\SharpDevelop\3.0\bin\Tools\Wix\heat.exe" dir "C:\Path\To\My\GameDir" -cg MyGameFilesGroup -dr INSTALLDIR -gg -out ".\Source\MyGameFiles.wxs" -var var.GameDeployFolder
Coordinator
Oct 4, 2009 at 9:43 PM

Great! Seems like I'm not up-to-date with WiX myself anymore :)

 

Oct 5, 2009 at 2:06 PM

Just to follow up, I got it working how I wanted it. To avoid the subfolder issue, I had to add "-srd" to the heat.exe arguments.

Then, I couldn't work out how to point a shortcut to a file in a different component, so resorted to a single manual step of removing the generated game component for the game exe and leaving it in Files.wxs with the child <shortcut> element.

Hope this helps somebody - it's a weight off my mind to have a pretty much automated msi builder set up.

Dec 3, 2010 at 9:16 AM
Edited Dec 3, 2010 at 9:28 AM

Hi, just came here to thanks roonda for his hints to automate the files inclusion. Works great so far :)

Just a question about the shortcut creation, I guess that in the "GameExecutable" section (in the files.wxs), I have to change Game.exe to my executable (let's say MyGame.exe), and in the Source, put "$(var.GameDeployFolder)\MyGame.exe", am I right?

 

Edit: Yes, this has to be done in order to create correctly the shortcut, plus, I have to remove the game executable from teh MyGamesFiles.wxs. Works great!

Mar 15, 2011 at 6:23 PM

hey guys, many thanks for the very valuable informations posted here. After some experimenting I successfully implemented your suggestions.

One thing I have to add. When I did it like roonda suggested, the output looked something similiar to the following (for each Component resp. file that I have in my Content folder):

<Component Id="SlimDX.DirectInput.xml" Directory="INSTALLDIR" Guid="{2AEB807C-1DF2-4995-AB23-28062B973282}">
    <File Id="fil23490001230121" KeyPath="yes" Source="$(var.GameDeployFolder)\SlimDX.DirectInput.xml" />
</Component>

What was wrong? The File-Id was a strange string everytime starting with "fil..." something. The File-Id is also the name after the copy of your particular files in the final installation directory. That means, that my game didn't found those files and thus didn't start.

So I had a check on the docks for heat.exe and found the following argument that helped to preserve my original file-name:

-suid  => Suppress unique identifiers for files, components, & directories.

finally resulting in:

"C:\Program Files\SharpDevelop\3.0\bin\Tools\Wix\heat.exe" dir "C:\Path\To\My\GameDir" -cg MyGameFilesGroup -dr INSTALLDIR -gg -suid -out ".\Source\MyGameFiles.wxs" -var var.GameDeployFolder

now everything works just like a little god for me ;-)

hope to helped newcomers like me - enjoy game programming and many thanks for this great post !!
Mar 15, 2011 at 6:24 PM

oh yeah... for comparision purposes, the final result looked like that:

<Component Id="SlimDX.DirectInput.xml" Directory="INSTALLDIR" Guid="{2AEB807C-1DF2-4995-AB23-28062B973282}">
    <File Id="SlimDX.DirectInput.xml" KeyPath="yes" Source="$(var.GameDeployFolder)\SlimDX.DirectInput.xml" />
</Component>

cheers, salocinx

Mar 15, 2011 at 6:48 PM

damn, I am using square brackets and the symbol @ in my filenames (such as " filename_[2@4] " for defining tiles). Heat.exe does substitute these special charaters with _

any ideas how to solve this problem?