WixFirewallExtension is a new WiX extension that lets you configure the Windows Firewall from your program’s installer. Windows has had a built-in firewall since Windows XP was released in 2001, though it was XP’s Service Pack 2 that introduced a firewall of sufficient power for most people to use it. (It helps that in SP2, the firewall is turned on by default. The same is true on Windows Vista, Server 2003 SP1, and Server 2008.)

Outgoing connections — from the local computer to a server — aren’t blocked. (In fact, the firewall on XP SP2 and Server 2003 SP1 doesn’t support blocking outbound connections. That feature was added to the firewall in Vista and Server 2008.) Incoming connections are blocked unless the firewall is configured to allow them. If your program is any kind of a server, it needs to add itself to the firewall’s exception list or it won’t receive any connections that originate from another machine.

There are two types of firewall exceptions:

  • Application: A particular program for an incoming connection on any port/protocol.
  • Port: A particular port for a particular IP protocol (TCP or UDP). Any program can accept incoming connections from that port/protocol.

For both types of exceptions, the scope of the exception controls which incoming connections are accepted:

  • Any network, including the Internet.
  • Only the local subnetwork.
  • Custom IP addresses.

You can configure your program’s firewall exceptions using the FirewallException element. To configure an application exception, nest the FirewallException element under the program’s File element or under a Component element and specify the program’s file id in the File attribute:

<Wix xmlns=”http://schemas.microsoft.com/wix/2006/wi” xmlns:fire=”http://schemas.microsoft.com/wix/FirewallExtension”>

<Component Id=”MyComponent1″ Guid=”PUT-GUID-HERE”>
<File KeyPath=”yes” Source=”program.exe”>
<fire:FirewallException Id=”FWX1″ Name=”My Program” />

The Id and Name attributes are both required. You can adjust the scope of the exception using the Scope attribute, which takes values any or localSubnet or by using RemoteAddress child elements:

<Wix xmlns=”http://schemas.microsoft.com/wix/2006/wi” xmlns:fire=”http://schemas.microsoft.com/wix/FirewallExtension”>

<Component Id=”MyComponent2″ Guid=”PUT-GUID-HERE”>
<File KeyPath=”yes” Source=”program.exe”>
<fire:FirewallException Id=”FWX2″ Name=”My Program”>
<fire:RemoteAddress>127.0.0.1</fire:RemoteAddress>
<fire:RemoteAddress>127.0.0.2</fire:RemoteAddress>
<fire:RemoteAddress>127.0.0.3</fire:RemoteAddress>

RemoteAddress is a direct line to the firewall API’s support for remote addresses.

There’s also a Program attribute that lets you specify a formatted string that identifies the program that should get the firewall exception. It’s useful if you want to specify an exception for a program installed by a different package.

To specify a port exception, use the Port and Protocol attributes. Port takes an integer value and Protocol takes tcp, udp, or any. Note that any requires Windows Vista and Server 2008; on XP SP2 and Server 2003 SP1, specify two port exceptions, one with Protocol=”tcp” and another with Protocol=”udp” as a workaround.

<Wix xmlns=”http://schemas.microsoft.com/wix/2006/wi” xmlns:fire=”http://schemas.microsoft.com/wix/FirewallExtension”>

<Component Id=”MyComponent3″ Guid=”PUT-GUID-HERE”>
<File KeyPath=”yes” Source=”program.exe”>
<fire:FirewallException Id=”FWX3″ Name=”My Program” Port=”1025″ Protocol=”udp” />

Both types of exceptions also support the IgnoreFailure attribute to specify whether firewall configuration failures should be ignored or cause the installation to roll back.

Sponsored by ACES

The firewall extension is part of the work I’m undertaking to convert ACES Studio’s products from our old script-based installer to a declarative installer built with WiX. Studio management was pleased to contribute the work to the WiX community.

Posted in Flight Simulator, WiX at May 17th, 2008. 7 Comments.

The feedback was quick and consistent: Marking files vital by default is a good thing. So in the next weekly release of WiX, files will get the msidbFileAttributesVital attribute by default. The FilesVitalByDefault property and -fdvital switch have been removed; in their place, SuppressFilesVitalByDefault and -sfdvital turn off the default “vital” behavior.

Posted in WiX at May 14th, 2008. 1 Comment.

The msidbFileAttributesVital File attribute bit says to Windows Installer that the file is vital to the operation of the installation and if it can’t be installed, the installation should fail. In an installation showing user interface, if a file can’t be installed, MSI shows a dialog box to let the user retry, ignore, or cancel the install. If a file is marked vital, however, the ignore option is taken away.

Generally, if a file can’t be installed, it’s bad news; most apps don’t react well to missing files. You might wonder why it’s not the default. Yeah, well, join the club. Unfortunately, it’s not the default and if you want “file vitality” in WiX, you need to set the Vital attribute to “yes” on every File element.

Providing better defaults is part of our ongoing attempts to make the WiX language easier to use and understand. Unfortunately, simply making Vital=”yes” the default would be a change in behavior. Granted, it’s a good change in behavior but we’re at a point in WiX v3 development and use where we generally avoid changes in behavior.

A minor new feature I added to WiX in the latest weekly release is the ability to indicate that all files should have the msidbFileAttributesVital bit set by default. If you use MSBuild projects, the FilesVitalByDefault property can be set for the whole project. If you use Candle directly, you have to specify -fdvital on every Candle command line invocation.

An alternative would be to reverse it: Set the msidbFileAttributesVital bit by default and let you turn off that behavior with another command-line switch or MSBuild property.

So we’re looking for feedback. Would it be disruptive to your use of WiX v3 to have the msidbFileAttributesVital bit set by default? Would it be preferable to using the new -fdvital switch or FilesVitalByDefault property?

Please post your votes/comments/questions/criticisms/concerns/praise here or via mail to the wix-users mailing list.

Posted in WiX at May 3rd, 2008. 6 Comments.

The Game Explorer is a new feature in Windows Vista to collect and richly present installed games. Game Explorer is a shell folder that includes detailed information about each game, including box art, content ratings (and parental-control restrictions based on them), and performance requirements (using the Vista performance rating system).

Most of the details shown in Game Explorer come from the game developer in the form of the Game Definition File (GDF) that’s embedded as a resource in your executable. Details and samples on the GDF and Game Explorer are available in the DirectX SDK, especially in Getting Started with Game Explorer.

The WiX Gaming extension is a compiler extension with custom actions to do the following:

  • Register a game in Game Explorer.
  • Create tasks in the context menu of a game in Game Explorer.
  • Register a game on Windows XP so it’s available in Game Explorer after an upgrade to Windows Vista.
  • Register extensions with support for the rich saved-game preview handler.

[Update: WixGamingExtension will be available in the next weekly release of WiX v3.]

Registering games

To register a game, add a Game element and specify its instance ID in its Id attribute as a child of the File element for the game executable. For example:

<File Id=”MyGameExeFile” Name=”passenger_simulator.exe” KeyPath=”yes”>
<gaming:Game Id=”985D5FD3-FC40-4CE9-9EE5-F2AAAB959230″>

The DirectX SDK suggests letting the Game Explorer COM object create a new GUID for every installation. It then suggests writing the new GUID to the registry or file system to persist it or to use WMI to query Game Explorer for the GUID. The prior release of Flight Simulator used WMI, which was a fairly regular source of failures during uninstall and repair operations. Following the mantra of minimizing runtime dependencies during setup, I chose to let the setup author specify a static ID. No persistence or runtime dependencies required.

Creating tasks

Game Explorer tasks are simply shortcuts shown on the context menu on the game icon in Game Explorer. Play tasks are plain ol’ shortcuts to the game executable with optional command-line arguments. Support tasks are shortcuts to URLs. The shortcuts must be created in specific directories for Game Explorer to find them.

WixGamingExtension translates strongly-typed PlayTask elements into rows in the Shortcut table; the Name attribute is the name of the shortcut and Arguments are the command-line arguments. WixGamingExtension translates SupportTask elements into WixUtilExtension InternetShortcuts; the Name attribute is the name of the shortcut and Address is the URL.

<File Id=”MyGameExeFile” Name=”passenger_simulator.exe” KeyPath=”yes”>
<gaming:Game Id=”985D5FD3-FC40-4CE9-9EE5-F2AAAB959230″>
<gaming:PlayTask Name=”Play” />
<gaming:PlayTask Name=”Play in Deity Mode” Arguments=”-deity” />
<gaming:SupportTask Name=”Help!” Address=”http://example.com” />
<gaming:SupportTask Name=”Cheat codes” Address=”http://example.com” />
<gaming:SupportTask Name=”Get P0wned” Address=”http://example.com/1337″ />
<gaming:SupportTask Name=”Get owned” Address=”http://example.com/non1337″ />
<gaming:PlayTask Name=”Show no mercy” Arguments=”-cutenfluffy” />
<gaming:SupportTask Name=”Forums” Address=”http://example.com” />
</gaming:Game>

Registering for OS upgrades

When you install a game on Windows XP and later install Windows Vista as an upgrade, the Vista upgrade can automatically register the game in Game Explorer. All that’s required is writing the task shortcuts and a few registry values. WixGamingExtension does that automatically; no extra authoring is required.

Rich saved games

Vista includes a special preview handler for file extensions registered as a saved-game file. Most of the effort required to support rich preview is in the game itself; the burden on setup is just to register the extension for the preview handler. WixGamingExtension supports this registration as a simple yes/no attribute on the standard WiX Extension element:

<ProgId Id=”MyGameProgId”>
<Extension Id=”MyGameSave” gaming:IsRichSavedGame=”yes” />
</ProgId>

Sponsored by ACES

The gaming extension is part of the work I’m undertaking to convert ACES Studio’s products from our old script-based installer to a declarative installer built with WiX. Studio management was pleased to contribute the work to the wider WiX community.

If you happen to publish a cool game that uses WixGamingExtension, feel free to send a copy my way. :-D

Posted in Flight Simulator, WiX at April 22nd, 2008. 3 Comments.

For flexibility at deployment time, MSI uses the value of the ALLUSERS property in determining the type of an installation—whether it’s per-machine or per-user. That lets a network administrator easily control whether the package’s shortcuts (for example) show up for all users or just one. There’s also the it-looks-good-at-first idea of ALLUSERS=2, which theoretically lets a package adapt to either an admin or non-admin user.

Problem is, in the era of UAC, a genuine per-user package wouldn’t require a prompt for elevation. Unfortunately, most “per-user” packages still need admin rights, because they still install to per-machine locations, like ProgramFilesFolder on the file system and HKEY_LOCAL_MACHINE in the registry.

To avoid lots of mysteriously failing packages, MSI 4.0 and later require packages to opt in as not requiring UAC elevation prompts. In WiX, that’s expressed by setting the Package/@InstallPrivileges attribute to limited. Confusingly, the default for ALLUSERS is null, which means to install the package per-user, so to get a per-machine package, you have to remember to instead set ALLUSERS to 1.

It’s easy enough to forget that, so I added the InstallScope attribute to the Package element to centralize the per-machine/per-user choice:

perMachine
Set this value to declare that the package is a per-machine installation and requires elevated privileges to install. Sets the ALLUSERS property to 1.
perUser
Set this value to declare that the package is a per-user installation and does not require elevated privileges to install. Sets the package’s InstallPrivileges attribute to “limited.”

This attribute doesn’t deprecate InstallPrivileges and you can use both (though it’s redundant to do so). If you specify perMachine, you must remove any Property element that sets ALLUSERS.

Posted in WiX at April 1st, 2008. 5 Comments.

A common request on wix-users is how to create shortcuts to a Web site. MSI’s Shortcut table and CreateShortcuts action don’t support targets that point to URLs like http://www.joyofsetup.com/. A shortcut’s target can point only to a feature (for advertised shortcuts) or a file or directory (for unadvertised shortcuts).

You can fake a shortcut to a URL by using the IniFile table to create a .url file. It’s a bit of a hack, given that the format of .url files isn’t explicitly documented and is therefore subject to change. (Granted, it’s not likely to change, because that would break a lot of existing applications.)

I needed URL shortcuts for Train Simulator so I wrote a custom action to create them. I then added authoring support to the WixUtilExtension compiler extension. With reviews from Heath and Peter, I checked in the work today. You’ll see it in the next weekly build of WiX v3.

The authoring is similar to, but simpler than, a standard shortcut. Here’s the attribute schema reference from WiX.chm:

Name Type Description Required
Id String Unique identifier in your installation package for this Internet shortcut. Yes
Directory String Identifier of the directory where the shortcut should be created. Yes
Name String The name of the shortcut file, which is visible to the user. (The .lnk extension is added automatically and by default, is not shown to the user.) Yes
Target String URL that should be opened when the user selects the shortcut. Windows opens the URL in the appropriate handler for the protocol specified in the URL. Note that this is a formatted field, so you can use [#fileId] syntax to refer to a file being installed (using the file: protocol). Yes

Here’s what a simple http shortcut looks like:

<util:InternetShortcut
Id=”Home”
Directory=”DesktopFolder”
Name=”Joy of Setup”
Target=”http://joyofsetup.com” />

You can also create shortcuts to resources using non-http protocols:

<util:InternetShortcut
Id=”ARP”
Directory=”ProgramMenuFolder”
Name=”ARP”
Target=”file://[%WINDIR]\Help\addremov.chm” />

Internet shortcuts are needed, among other reasons, for Vista’s Game Explorer. More on that in a future entry.

Posted in Flight Simulator, WiX at March 18th, 2008. 11 Comments.

Working with multi-gigabyte setups has taught me that compressing cabinets can be very time-consuming. Of course, it can also be vital — Flight Simulator X barely fit on two DVDs; without high compression, it would have required a third disc.

As I work on the WiX tooling and authoring for upcoming products, I knew I needed to support multiple compression levels: no/low compression for developer builds, “normal” MSZip compression for daily builds, and high compression for milestone builds.

By default, a Media element with no CompressionLevel attribute gets MSZip compression, which offers a nice compression-to-time ratio. A typical approach to control compression level outside the authoring is to pass in a preprocessor variable via the MSBuild project and use its value in Media/@CompressionLevel. That works but is kind of clunky.

So I decided to address the clunkiness by adding support to override the default MSZip compression level. Here are the two steps to take advantage of this feature:

  1. Author Media elements with a Cabinet attribute but without a CompressionLevel attribute.
  2. Pass -dcl:level on the Light command line, where level is none, low, medium, high, or mszip.
    –or–
    Declare the DefaultCompressionLevel property in your MSBuild project file, with a value of none, low, medium, high, or mszip.

There are no changes in behavior with existing authoring or build scripts. If you omit Media/@CompressionLevel and don’t use -dcl or DefaultCompressionLevel, you’ll continue to get MSZip compression.

This change will appear in the next weekly release of WiX v3.

Posted in WiX at January 28th, 2008. 10 Comments.

The Windows Home Server folks have an SDK for extending the server with what they call “add-ins.” Their deployment sample is written with WiX. I love to see that, so I’m looking into what setup functionality would make a useful WHS extension for WiX. Right now, it doesn’t look like there’s much required — the requirements of a WHS add-in installer are pretty minimal over and above a good installer in general.

One thing they mention is detecting WHS if your add-in requires it. It’s not one of the standard Operating System Properties that MSI provides (yet, at least). The WHS SDK recommends calling the GetVersionEx API function. Clearly, it’s time for a custom action: Enter WixQueryOsInfo.

I wanted to follow the same model as MSI; that is, set a property if the OS running the package is of a particular edition or supports a particular feature. That lets you use them in conditions for features or components that only make sense when the user is running a supported OS or configuration.

As I’d be writing a CA to call GetVersionEx, I looked at what else it could detect that MSI didn’t already support. There were several, though sometimes the MSI naming convention didn’t match how GetVersionEx named them. So I decided to set properties for everything GetVersionEx offered using its naming convention. That way, it’s easy to mentally translate from the GetVersionEx doc to the properties WixQueryOsInfo sets.

Then, while I was in there, I added another CA to do something similar: WixQueryOsDirs sets properties for the “special folders” Windows defines for system and user directories. MSI already supports a long list of System Folder Properties but there are extra ones that Windows supports. For WixQueryOsDirs, I didn’t duplicate the ones MSI already supports.

Using WixQueryOsInfo and WixQueryOsDirs

The CAs are part of WixUtilExtension so you need to link with the “-ext WixUtilExtension” switch. Your WiX source must reference the CAs via their properties, to cause the linker to pull in the DLL and sequencing:

<Product …>
<PropertyRef Id=”WIX_SUITE_SINGLEUSERTS” />
<PropertyRef Id=”WIX_DIR_COMMON_DOCUMENTS” />
</Product>

Note that WixQueryOsInfo and WixQueryOsDirs both always set all the properties that apply, regardless of which you specify via PropertyRef. The PropertyRef just pulls in the CA, the DLL in the Binary table, and InstallExecuteSequence and InstallUISequence scheduling.

Look for OSInfo in the next weekly release of WiX v3.

Here’s the documentation page that’s part of WiX.chm:

OSInfo custom actions

The WixQueryOsInfo and WixQueryOsDirs custom actions in wixca (part of WixUtilExtension) set properties over and above the MSI set for OS product/suite detection and standard directories. Here’s a complete list:

WixQueryOsInfo properties

WIX_SUITE_BACKOFFICE

Equivalent to the OSVERSIONINFOEX VER_SUITE_BACKOFFICE flag.

WIX_SUITE_BLADE

Equivalent to the OSVERSIONINFOEX VER_SUITE_BLADE flag.

WIX_SUITE_COMMUNICATIONS

Equivalent to the OSVERSIONINFOEX VER_SUITE_COMMUNICATIONS flag.

WIX_SUITE_COMPUTE_SERVER

Equivalent to the OSVERSIONINFOEX VER_SUITE_COMPUTE_SERVER flag.

WIX_SUITE_DATACENTER

Equivalent to the OSVERSIONINFOEX VER_SUITE_DATACENTER flag.

WIX_SUITE_EMBEDDEDNT

Equivalent to the OSVERSIONINFOEX VER_SUITE_EMBEDDEDNT flag.

WIX_SUITE_EMBEDDED_RESTRICTED

Equivalent to the OSVERSIONINFOEX VER_SUITE_EMBEDDED_RESTRICTED flag.

WIX_SUITE_ENTERPRISE

Equivalent to the OSVERSIONINFOEX VER_SUITE_ENTERPRISE flag.

WIX_SUITE_MEDIACENTER

Equivalent to the GetSystemMetrics SM_SERVERR2 flag.

WIX_SUITE_PERSONAL

Equivalent to the OSVERSIONINFOEX VER_SUITE_PERSONAL flag.

WIX_SUITE_SECURITY_APPLIANCE

Equivalent to the OSVERSIONINFOEX VER_SUITE_SECURITY_APPLIANCE flag.

WIX_SUITE_SERVERR2

Equivalent to the GetSystemMetrics SM_SERVERR2 flag.

WIX_SUITE_SINGLEUSERTS

Equivalent to the OSVERSIONINFOEX VER_SUITE_SINGLEUSERTS flag.

WIX_SUITE_SMALLBUSINESS

Equivalent to the OSVERSIONINFOEX VER_SUITE_SMALLBUSINESS flag.

WIX_SUITE_SMALLBUSINESS_RESTRICTED

Equivalent to the OSVERSIONINFOEX VER_SUITE_SMALLBUSINESS_RESTRICTED flag.

WIX_SUITE_STARTER

Equivalent to the GetSystemMetrics SM_STARTER flag.

WIX_SUITE_STORAGE_SERVER

Equivalent to the OSVERSIONINFOEX VER_SUITE_STORAGE_SERVER flag.

WIX_SUITE_TABLETPC

Equivalent to the GetSystemMetrics SM_TABLETPC flag.

WIX_SUITE_TERMINAL

Equivalent to the OSVERSIONINFOEX VER_SUITE_TERMINAL flag.

WIX_SUITE_WH_SERVER

Windows Home Server. Equivalent to the OSVERSIONINFOEX VER_SUITE_WH_SERVER flag.

WixQueryOsDirs properties

WIX_DIR_ADMINTOOLS

Per-user administrative tools directory. Equivalent to the SHGetFolderPath CSIDL_ADMINTOOLS flag.

WIX_DIR_COMMON_ADMINTOOLS

All-users administrative tools directory. Equivalent to the SHGetFolderPath CSIDL_COMMON_ADMINTOOLS flag.

WIX_DIR_COMMON_DOCUMENTS

All-users documents directory. Equivalent to the SHGetFolderPath CSIDL_COMMON_DOCUMENTS flag.

WIX_DIR_COOKIES

Per-user Internet Explorer cookies directory. Equivalent to the SHGetFolderPath CSIDL_COOKIES flag.

WIX_DIR_HISTORY

Per-user Internet Explorer history directory. Equivalent to the SHGetFolderPath CSIDL_HISTORY flag.

WIX_DIR_INTERNET_CACHE

Per-user Internet Explorer cache directory. Equivalent to the SHGetFolderPath CSIDL_INTERNET_CACHE flag.

WIX_DIR_PERSONAL

Per-user documents directory. Equivalent to the SHGetFolderPath CSIDL_PERSONAL flag.

To use the WixQueryOsInfo and WixQueryOsDirs custom actions, add PropertyRef elements for the properties above you want to be set and add WixUtilExtension to your link options (a.k.a. the Light command line). For example:

<PropertyRef Id="WIX_SUITE_SINGLEUSERTS" />
<PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS" />

WixUtilExtension automatically schedules the custom actions as needed after the AppSearch standard action.

Posted in WiX at April 29th, 2007. 1 Comment.