There is an ongoing thread on the XNA Creators Club forums about how to create an installer using Inno Setup, a free and very capable installer program.
The script described by Pelle in the first posts of this thread works great for XNA GSE 1.0 and Refresh, but is problematic for XNA GS 2.0 games because of the dependency on .NET 2.0 Service Pack 1. I won’t bring much new information in this post, but will try to summarize everything I read and tried it into a tested & true solution that I’m currently using for the Fez installer.
Please note that this solution does not work if your game requires use of the GamerServicesComponent of live networking using XNA, since you need the whole Game Studio for it to work. (see this post)
Also, it wasn’t made with 64-bit operating systems in mind, so if you’re going to support them you’ll have to modify it. It has been known to work on Vista though.
The problem
The problem we’re trying to address is the following : XNA Game Studio 2.0 requires many things to be installed, all of which are described in FAQ in the forums and (with more detail) in this excellent blog post by Ed Andersen.
Among those, there is the .NET Framework 2.0 Service Pack 1, which weighs an astonishing 23.6Mb and often doubles (or more!) the size of your average XNA casual game.
The solutions
Knowing this, there are a couple of solutions possible :
- Use the “Download” feature of ISTool to make the user download the 23Mb behemoth only if it’s absolutely necessary.
- Ed and the ZMan both explain that if you have .NET 2.0 installed, only the Visual C++ 2005 Service Pack 1 Redistributables suffice, which weighs only 2.6Mb.
- The only lightweight web installer that contains everything XNA 2.0 needs is the .NET Framework 3.5, which at 2.7Mb can be easily bundled to your application. But then, I find that forcing the 3.0, 3.0SP1 and 3.5 .NET Frameworks a bit invasive when all you want to do is get 2.0SP1.
So what I ended up doing is an hybrid approach. If .NET 2.0 is not installed, download and install the .NET 2.0 SP1. If .NET 2.0 is installed but no service pack, install the VC++ redistributable. If it’s all in, nothing is downloaded and nothing installed.
The script
I didn’t find any way to conditionally download different files, for example download the VC++ redist only if needed, AND .NET 2.0 SP1 if needed. All downloadable files go in a single condition, as far as I understand. So VC++ and the DirectX Web Setup need to be bundled to the application, a small price to pay at 2.6Mb and 281Kb respectively.
Here’s the Inno Setup/ISTool 5.2.1 script that I ended up making, starting from the [Files] section, so assuming you’ve got the rest of your script above that.
[Files]
Source: Resourcesvcredist_x86.exe; DestDir: {tmp}; Check: ShouldInstallVCPPSP1
Source: Resourcesdxwebsetup.exe; DestDir: {tmp}; Check: ShouldInstallDX
Source: Resourcesxnafx20_redist.msi; DestDir: {tmp}; Check: ShouldInstallXNA2
Source: MyGameFiles*; DestDir: {app}; Flags: recursesubdirs
// You will usually want an [Icons] section here
[Run]
Filename: {tmp}vcredist_x86.exe; Parameters: /q; Check: ShouldInstallVCPPSP1
Filename: {tmp}NetFx20SP1_x86.exe; Flags: skipifdoesntexist; Parameters: /q /norestart
Filename: {tmp}dxwebsetup.exe; Parameters: /Q; Check: ShouldInstallDX
Filename: msiexec.exe; Parameters: "/quiet /i ""{tmp}xnafx20_redist.msi"""; Check: ShouldInstallXNA2
Filename: {app}{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent
[_ISToolDownload]
Source: http://www.microsoft.com/downloads/info.aspx?na=90&p=&SrcDisplayLang=en&SrcCategoryId=&SrcFamilyId=79bc3b77-e02c-4ad3-aacf-a7633f706ba5&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f0%2f8%2fc%2f08c19fa4-4c4f-4ffb-9d6c-150906578c9e%2fNetFx20SP1_x86.exe; DestDir: {tmp}; DestName: NetFx20SP1_x86.exe
[Code]
var dxMissing: Boolean; // Are the required DirectX components missing?
var xna2Missing: Boolean; // Is the XNA 2.0 Framework missing?
var dotNET2Missing: Boolean; // Is the .NET 2.0 Framework missing entirely?
var onlySP1Missing: Boolean; // Is .NET 2.0 present but with no Service Pack?
function InitializeSetup(): Boolean;
var spval: Cardinal; // Identifies the installed .NET 2.0 Service Pack
begin
// Test the presence of XNA 2.0
if (not(RegKeyExists(HKLM, 'SOFTWAREMicrosoftXNAFrameworkv2.0'))) then
xna2Missing := True;
// Test the presence of required DirectX components
if (not(FileExists(ExpandConstant('{sys}xinput1_3.dll')) and
FileExists(ExpandConstant('{sys}x3daudio1_2.dll')) and
FileExists(ExpandConstant('{sys}d3dx9_31.dll')) and
FileExists(ExpandConstant('{sys}xactengine2_9.dll')))) then
dxMissing := True;
// Test the presence of .NET 2.0 and SP1
if (not(RegKeyExists(HKLM, 'SOFTWAREMicrosoftNET Framework SetupNDPv2.0.50727'))) then
dotNET2Missing := True
else if (not(RegQueryDWordValue(HKLM, 'SOFTWAREMicrosoftNET Framework SetupNDPv2.0.50727', 'SP', spval))) then
onlySP1Missing := True
else if (spval < 1) then
onlySP1Missing := True;
Result := True;
end;
function NextButtonClick(CurPage: Integer): Boolean;
begin
// Only download if .NET 2.0 is missing entirely
if (dotNET2Missing) then
Result := ISTool_Download(CurPage)
else
Result := True;
end;
// The following functions are called by "Check" directives
function ShouldInstallVCPPSP1(): Boolean;
begin
Result := onlySP1Missing;
end;
function ShouldInstallXNA2(): Boolean;
begin
Result := xna2Missing;
end;
function ShouldInstallDX(): Boolean;
begin
Result := dxMissing;
end;
Some might say that checking for every component and not extracting/installing them unless absolutely necessary is overkill, but it does cut down on the install time, and your users get to play your game sooner! :)
So there you have it. Probably the most optimized/less invasive Inno Setup script that can be for XNA 2.0 games.
Comments/suggestions/corrections?
This line: Result := ISTool_Download(CurPage)
keeps giving me a compiler error saying that ISTool_Download doesn’t exist. Any ideas?
Yep, this is most probably because you’re using the straight Inno Setup compiler, the download module is party of ISTool, so you need to compile it from the ISTool IDE.
Great stuff other than the fact that you are not allowed to bundle the dx webinstaller in this way. Microsoft have told us that they reserve the right to change where the dx webinstaller gets its files from so the only 100% valid web installer is the one you get when you hit the website and they do change it.
So one day your installer will run its private copy and it will fail
Yes this sucks.. .I have bitched about it for almost 3 years now and Microsoft say ‘we dont see it as a problem’…
You have 2 choices – bundle the dxsetup.exe and the required files. Or shell out to IE and tell your users to run the setup they find there. One makes the installer bigger and the other is a terrible experience. We can’t win.
Drop me an email if you want to chat about it… the MVP summit is coming up so I will once again me trying to get this changed.
Thanks! I used your code and I can finally get my XNA game working on different machines :)
I know this is sorta off topic. I am trying to use the 1.0 refresh one. And i get this funky error message with the compiler.
Could not copy ” C:Program FilesInno Setup 5SETUPLDR.E32″ to “C:Program FilesISToolOutputsetup.exe”. Error 5: Access is denied
That is quite funky indeed. Never seen it, no idea.
I’ll play the “dumb technical support telephonist”, try to restart your computer or reinstall Inno Setup!
Michael, whenever I see an Access is denied, 90% chance you are on Vista and aren’t running Inno with administrative rights, especially if it’s trying to copy a file into Program Files, which is “write protected” by default.