Creating a PC Executable for XNA 4.0

I’m gearing up to release Pixel Blocked! for the PC. One of the things I’ve been working on the past few days was creating an all-inclusive executable that would install the game and software prerequisites that aren’t already installed on the player’s machine. My problem was that I couldn’t really find one that I liked online. I’m sure other XNA developers feel the same way, so I’m sharing this script I’ve created for Inno Setup that will create an elegant executable for your XNA 4.o games.

I’ve built off of the script edited by David Amador that you can find here. It was made for XNA 3.1, but with a small tweak, I also had it working with XNA 4.o. Although functional, there were a few things I didn’t like about it. When it installs the prerequisites, the UI hangs with the message “Finishing installation…”. On slower computers, this could actually take anywhere from 2-20 minutes, a process that is very misleading to the user. It looks like the installation is frozen. Another issue is that it will always install the XNA framework even if the user already has it installed on their machines. That’s an unnecessary step that slows the installation process.

I’ve made extensive changes to the script (especially the pascal code) so that the installation is more transparent to the user. It’ll tell the user when it’s installing the prerequisites and also show a progress bar as they are installing. The executable is also all-inclusive, so that they don’t have to download and install anything else. It’s a simple setup that will properly check for prerequisite software and only install them if needed.

Without further ado, here’s the code.


; Script generated by the Inno Setup Script Wizard.
; (Then extensively modified by Caliban Darklock.)
; (And yet again modified by David Amador)
; (And again extensively modified by Daniel Truong)
; Now works for XNA 4.0, installation is also more transparent when installing prerequisites.
; Shows progress bar for XNA and DotNet redistributables and skips them if already installed.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

; Enter the name of your game here
#define MyAppName "Pixel Blocked!"
; Enter the name of your game and a version number here
#define MyAppVerName "Pixel Blocked v1.2"

; Enter the name of your company, or just your name
#define MyCompany "Daniel Truong"

; Enter the URL of your website
#define MyAppURL "http://pixelblocked.com/"

; Enter the path to your game project - check Visual Studio properties for the path
#define MyAppLocation "C:\Users\Daniel\Documents\Personal Subversion Repositories\Pixel Blocked\Blocks On A Plane\Blocks On A Plane"

; Enter the name of your game executable
#define MyAppExeName "Pixel Blocked!.exe"

; Enter the location where XNA Game Studio is installed
#define MyGameStudioLocation "C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v4.0"

; Enter the name for the correct version of the XNA Framework MSI
#define XNARedist "xnafx40_redist.msi"

; Enter the location where you have placed the .NET redistributable
#define MyRedistLocation "D:\Game Development Tools"

; Download .NET 4.0 from <a href="http://www.microsoft.com/en-us/download/details.aspx?id=24872">http://www.microsoft.com/en-us/download/details.aspx?id=24872</a>
; enter the name of the executable file here
 #define DotNetSetup "dotNetFx40_Full_x86_x64.exe"

; Once you've filled in all the variables above and downloaded your redist packages,
; everything under this point should JUST WORK for most XNA projects.

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyCompany}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputBaseFilename={#MyAppName} Setup
Compression=lzma
SolidCompression=yes
SetupIconFile = "C:\Users\Daniel\Documents\Personal Subversion Repositories\Pixel Blocked\Blocks On A Plane\Blocks On A Plane\Game.ico"

[Languages]
Name: english; MessagesFile: compiler:Default.isl

[Tasks]
Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked

[Files]
; XNA Framework redistributable
Source: {#MyGameStudioLocation}\Redist\XNA FX Redist\{#XNARedist}; DestDir: {tmp}

; .NET redistributables
Source: {#MyRedistLocation}\{#DotNetSetup}; DestDir: {tmp}

; The game itself
Source: {#MyAppLocation}\bin\x86\Release\{#MyAppExeName}; DestDir: {app}; Flags: ignoreversion
Source: {#MyAppLocation}\bin\x86\Release\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName}
Name: {group}\{cm:UninstallProgram,{#MyAppName}}; Filename: {uninstallexe}
Name: {commondesktop}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: desktopicon

[Run]
Filename: {tmp}\{#DotNetSetup}; Flags: skipifdoesntexist; StatusMsg: "Installing required component: .NET Framework 4.0 Client."; Parameters: "/norestart /passive"; Check: CheckNetFramework
Filename: msiexec.exe; StatusMsg: "Installing required component: XNA Framework Redistributable 4.0 Refresh."; Parameters: "/qb /i ""{tmp}\{#XNARedist}"; Check: CheckXNAFramework
Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent

[Code]
function IsDotNetDetected: boolean;
var
    key: string;
    install: cardinal;
    success: boolean;

begin
    WizardForm.StatusLabel.Caption := 'Checking for .Net Framework 4.0 Client.';
    key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client';
    success := RegQueryDWordValue(HKLM, key, 'Install', install);
    result := success and (install = 1);
end;
function CheckNetFramework: boolean;
begin
    if IsDotNetDetected then begin
        WizardForm.StatusLabel.Caption := '.Net Framework 4.0 Client detected.';
    end;
    result := not IsDotNetDetected;
end;

function IsXNAFrameworkDetected: Boolean;
var
    key: string;
    install: cardinal;
    success: boolean;

begin
    WizardForm.StatusLabel.Caption := 'Checking for XNA Framework Redistributable 4.0 Refresh.';
    if IsWin64 then begin
        key := 'SOFTWARE\Wow6432Node\Microsoft\XNA\Framework\v4.0';
    end else begin
        key := 'SOFTWARE\Microsoft\XNA\Framework\v4.0';
    end;
    success := RegQueryDWordValue(HKLM, key, 'Installed', install);
    result := success and (install = 1);
end;

function CheckXNAFramework: boolean;
begin
    if IsXNAFrameworkDetected then begin
        WizardForm.StatusLabel.Caption := 'XNA Framework Redistributable 4.0 Refresh detected.';
    end;
    result := not IsXNAFrameworkDetected;
end;

Steps to get it working:

  1. Download and install Inno Setup.
  2. Download the .NET redistributable.
  3. Copy and paste the code above into an Inno Setup script file.
  4. Replace all #define constants with your own values.
  5. Compile and enjoy!
Advertisements

13 thoughts on “Creating a PC Executable for XNA 4.0”

  1. I have observed that in the world nowadays, video games are the latest rage with children of all ages. Occasionally it may be difficult to drag your kids away from the video games. If you want the best of both worlds, there are various educational games for kids. Interesting post.

  2. Perfect script, it worked at first try and everything is included.
    I tried many other scripts and tools, but this is by far the most efficient and easy to handle 🙂
    Thanks a lot for sharing this !

  3. Greetings from California! I’m bored at work
    so I decided to check out your blog on my iphone during lunch
    break. I really like the info you present here
    and can’t wait to take a look when I get home.
    I’m surprised at how fast your blog loaded on my phone .. I’m not even using WIFI, just 3G ..

    Anyways, amazing blog!

    1. Sure, I’ll try to get around to updating and testing it for Windows 8 by the weekend. It’s been awhile, I’m surprised no one has mentioned it earlier.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s