Windows Installer: Removing Folders

Recently I put together a Windows Installer package (MSI file) for our team to use internally.

Without you having to do any extra work, the Windows Uninstaller automatically takes care of deleting any folders where it installed content. However, if an app writes to other folders that the installer doesn’t know about, it’s your responsibility to handle the removal of those folders.

In my case, the app that I was installing writes temporary files to a cache folder. The app could cache gigabytes of data, so it was key that the uninstall remove all those temporary files. Fortunately, WiX makes this easy. Here are the steps. First, we search the registry for the location of the cache folder and store it in a Property. We’ll use this if we’re uninstalling. Replace CompanyName and AppName with your company and app names.

<?define AppRegKey = "Software\CompanyName\AppName" ?>
<Property Id="CACHEFOLDER">
 <RegistrySearch Key="$(var.AppRegKey)" Root="HKCU" Type="raw"
 Id="CacheFolderRegSearch" Name="CachePath" />

Second, in the case we’re installing, we need to save the location of the cache folder in the registry, so that we can invoke the “RemoveFolderEx” command on that folder during a future uninstall.

<?define AppCacheFolder = "AppCache" ?>
<Component Id="CacheCleanup" Guid="*">
 <RegistryValue Root="HKCU" Key="$(var.AppRegKey)"
 Name="CachePath" Type="string" Value="[TempFolder]$(var.AppCacheFolder)" KeyPath="yes" />
 <util:RemoveFolderEx On="uninstall" Property="CACHEFOLDER"/>

We need to reference the component we’ve registered in a Feature block, along with other relevant components.

<Feature Id="MainApplication" Title="App Name" Level="1">
 <ComponentRef Id="OtherComponents" />
 <ComponentRef Id="CacheCleanup" />

To make this all work correctly, there are two more steps. First, ensure your WSX source references the utility extension where util:RemoveFolderEx is located.

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns = ""
     xmlns:util = "">

And second, reference the extension when you compile and link:

candle source.wxs -ext WixUtilExtension.dll
light source.wixobj -ext WixUtilExtension.dll

That’s it. Now the installation will correctly store a registry reference to the cache folder and clean up the cache folder on uninstall.

Posted in Computers and Internet, Installers, Microsoft, WiX | Leave a comment

Windows Installer: Firewall Settings

Recently I put together a Windows Installer package (MSI file) for our team to use internally.

The app I was installing communicates with other apps on our internal network, and it requires certain network ports be open for ICMP and TCP communication.

My first thought on solving this issue was to figure out where Windows Firewall Manager stores its firewall settings and then tell the firewall to read the new settings. Indeed, I found the location in the registry and I was able to successfully create the new settings. I was also able to kick the firewall using the commands “net stop “windows firewall”” followed immediately by “net start “windows firewall””. Everything seemed great.

But there were issues. For instance, during install, a little message showed up in the taskbar that the firewall was stopping. That’s confusing to the end user, especially because there’s no message that shows up saying the firewall is starting back up. Modifying the registry directly felt dirty. This was not a maintainable solution. The whole approach was a hack.

So I found a better way: the “netsh advfirewall” command. It’s available on Windows 7 and up.

Say you wanted to open ports 8008 and 8009 for inbound TCP traffic on the local network. Here’s the full command to add that rule:

netsh advfirewall firewall add rule name="My Firewall Rule" dir=in action=allow enable=yes protocol=tcp interfacetype=lan localport=8008,8009 remoteport=8008,8009

Even better, the firewall automatically starts applying this rule without a restart. There are many other advfirewall parameters, but you can explore those on your own.

Running these commands in the context of the installer was a little more challenging. I needed to add multiple rules, and I needed to handle removing the rules on uninstall. Let’s start with the variables I used to simplify things:

<?define Quote = """ ?>
<?define IpRange = "w.x.y.z-w.x.y.z" ?>
<?define OpenPorts = "8008,8009" ?>
<?define FirewallRuleName = "$(var.Quote)Open 8008 and 8009 for MyProject$(var.Quote)"?>
<?define FirewallAddRule = "advfirewall firewall add rule name=$(var.FirewallRuleName) dir=in action=allow enable=yes" ?>
<?define FirewallRuleICMP = "remoteip=$(var.IpRange) protocol=icmpv4 interfacetype=lan" ?>
<?define FirewallRuleTCP = "remoteip=$(var.IpRange) protocol=tcp interfacetype=lan localport=$(var.OpenPorts) remoteport=$(var.OpenPorts)" ?>
<?define FirewallRemoveRule = "advfirewall firewall delete rule name=$(var.FirewallRuleName)" ?>

The Quote variable handles the cases where we need to embed quotes in the command string. The IpRange variable locks this rule down to a specific set of IPs. Fill in your own values for w.x.y.z. Like many other advfirewall commands, it’s optional. FirewallAddRule has the meat of the command string, and then there are individual suffixes for the ICMP and TCP rules. The ICMP rule doesn’t accept ports. The FirewallRemoveRule ensures that all rules matching the given name will be removed on uninstall.

Here’s the code for executing these rules. First, for install:

<CustomAction Id="SetUpdateFirewallICMPCmd" Property="UpdateFirewallICMP" Execute="immediate"
 Value="&quot;netsh&quot; $(var.FirewallAddRule) $(var.FirewallRuleICMP)" />
<CustomAction Id="UpdateFirewallICMP" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred"
 Return="ignore" Impersonate="no" />
<CustomAction Id="SetUpdateFirewallTCPCmd" Property="UpdateFirewallTCP" Execute="immediate"
 Value="&quot;netsh&quot; $(var.FirewallAddRule) $(var.FirewallRuleTCP)" />
<CustomAction Id="UpdateFirewallTCP" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred"
 Return="ignore" Impersonate="no" />
<Custom Action="SetUpdateFirewallICMPCmd" Before="InstallFinalize"><![CDATA[NOT REMOVE]]></Custom>
<Custom Action="UpdateFirewallICMP" After="SetUpdateFirewallICMPCmd"><![CDATA[NOT REMOVE]]></Custom>
<Custom Action="SetUpdateFirewallTCPCmd" After="UpdateFirewallICMP"><![CDATA[NOT REMOVE]]></Custom>
<Custom Action="UpdateFirewallTCP" After="SetUpdateFirewallTCPCmd"><![CDATA[NOT REMOVE]]><Custom>

There are four custom actions that execute in sequence after the InstallFinalize stage. The first action establishes the command line for adding the ICMP rule using the variables defined above. CAQuietExec requires that the actual app command (netsh in this case) be quoted. The second action executes the command line established in the first command. Using multiple CAQuietExecs requires configuring the command line as a property with a matching ID in the following action. Changing firewall settings requires Windows elevated privilege, so we use deferred execution with no impersonation. The final two commands set the TCP rule in the same manner.

The funky notation ![CDATA[NOT REMOVE]] tells the installer that these commands should run whenever we’re not actually uninstalling the product (e.g. installs, reinstalls, upgrades, repairs).

Here’s uninstall:

<CustomAction Id="SetUpdateFirewallRemoveCmd" Property="UpdateFirewallRemove" Execute="immediate"
 Value="&quot;netsh&quot; $(var.FirewallRemoveRule)" />
<CustomAction Id="UpdateFirewallRemove" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred"
 Return="ignore" Impersonate="no" />
<Custom Action="SetUpdateFirewallRemoveCmd" Before="InstallFinalize">
<Custom Action="UpdateFirewallRemove" After="SetUpdateFirewallRemoveCmd">

We set up the command line to remove the firewall settings, then invoke that command line with elevated privileges. We only remove the firewall settings when the product is being uninstalled (not installed, reinstalled, or upgraded)

One additional note. I really wanted to lock down the firewall rule to a specific app, so I was excited that advfirewall has just the option I was looking for:

allowedprogram program=C:\MyApp\MyApp.exe name="My Application"

But unfortunately in my particular case the app I was installing is not actually the app that does all the LAN communication. My app spawns other apps that do the communication, and the locations and names of those apps is not necessarily known at install time. Hence we chose to lock down the firewall rules to specific (small) range of IPs, so that if this install package gets out in the wild it’s not unnecessarily introducing security holes.


Posted in Computers and Internet, Installers, Microsoft, WiX | Leave a comment

Windows Installer: Modify Config Files

Recently I put together a Windows Installer package (MSI file) for our team to use internally.

The app I was installing writes to temporary storage, and the app stores a reference to the temporary storage folder in AppConfig.xml, which is included in the install manifest. AppConfig.xml contains a folder specifier like this:


The problem I faced was that I wanted to avoid using a hardcoded “c:\cache.” Not every user has a C drive or wants a cache folder at the root. And I didn’t want the user to have to configure this manually. The installer should default to a reasonable location.

Fortunately, WiX handles this sort of thing with aplomb. You can modify the contents of XML files at install time. Perfect!

Here’s how. In the WXS manifest, add an XML setValue action to modify XML contents.

<?define AppConfigFile = "AppConfig.xml" ?>
<?define CacheFolder = "cache" ?>

<DirectoryRef Id="InstallDir">
  <Component Id="Config" Guid="<your-GUID-here>">
    <File Id="Config" Source="$(var.AppConfigFile)" KeyPath="yes"/>
    <util:XmlFile Id="Cache" File=[#MyAppConfig]"
      Action="setValue" ElementPath="//Options/CacheFolder"
      Value="[TempFolder]$(var.CacheFolder)" />

Here’s what’s happening. You define your file component as normal. After you’ve specified the file information, use the util:XmlFile specifier. XmlFile File points at the actual file by using the # specifier, which resolves to the full install path of AppConfig.xml. Change the XML value of to “%temp%cache”, which resolves to the user’s temporary folder plus “cache,” e.g. “c:\users\pete\AppData\Local\Temp\cache” — just what we want.

To make this all work correctly, there are two more steps. First, ensure your WSX source references the utility extension where util:XmlFile is located.

<?xml version="1.0" encoding="UTF-8"?>
  <Wix xmlns = ""
       xmlns:util = "">

And second, reference the extension when you compile and link:

candle source.wxs -ext WixUtilExtension.dll
light source.wixobj -ext WixUtilExtension.dll

That’s it. Now the installation modifies the config file so your app automatically caches data to the user’s personalized temporary folder.

Posted in Computers and Internet, Installers, Microsoft, WiX | Tagged , , | Leave a comment

Windows Installer: Shut down System Tray Apps

Recently I put together a Windows Installer package (MSI file) for our team to use internally. The package installs a system tray app (sometimes called a notification app or notification area app). One common property of system tray apps is that they don’t actually close on exit — they simply return to the system tray and continue running in the background.

In order to properly uninstall this component, the app needs to be shut down by the installer/uninstaller. Typically, in WiX, you’d do this with the CloseApplication element, which sends a WM_CLOSE message to the system tray app, which it ignores completely. What to do?

Here was my solution, embedded in the WiX WXS source file (toolset v3.9):

<?define SysTrayAppExe = "mySysTrayApp.exe" ?>

<CustomAction Id="KillApp" Directory="InstallDir" Return="ignore" ExeCommand="&quot;[SystemFolder]taskkill.exe&quot; /F /IM &quot;$(var.SysTrayAppExe)&quot;" />

First, we define a custom action that will execute the taskkill Windows system command. We ignore the return value because we don’t care if the app was actually running. Just in case the Windows system folder has embedded spaces, we wrap the command in quotes using the XML quote specifier. The /F flag requests a forceful termination, and the /IM flag requests that we terminate the specifically named process, which is again wrapped in quotes in case it has embedded spaces.

Next, we set up the custom action to execute in the first phase of the install process. This ensures that the system tray app is always shut down when the install/uninstall begins.

Ideally, we’d use the CAQuietExec special custom action to avoid a command screen from briefly flashing on the screen, but CAQuietExec must be run after the InstallInitialize phase, by which time the Windows Installer has already detected that the system tray app is running, and it’s too late for us to do anything about it.

Posted in Computers and Internet, Installers, Microsoft, WiX | Tagged , , | Leave a comment

VR Toolset

It was fun to compare and contrast the toolset we’re using at HBO for the creation of VR products with what the folks at Oculus Story Studio are using. More similarities than differences. Story Studios’ Dropbox solution as a backup system is rather clever.

Posted in Computers and Internet, Game Programming, VR | Leave a comment

VR: Inside Looking Out

For the past year, I’ve been working on virtual reality projects at HBO. We’ve learned a ton, but there is still so much we don’t know.

Although VR experiences borrow from the language of film and borrow from the language of video games, one of the most important things we’ve learned is that VR is truly a new medium.

With traditional media, you are on the outside looking in. You read a book. You watch a movie. You play a game. The view you have of the book or the film or the game is a window into another world. It may be an immersive experience, but you can easily exit that experience by simply casting your gaze in a different direction.

With virtual reality, you’re on the inside looking out. You can’t look away, because everywhere you turn is part of the experience that’s been created for you.

Perhaps the most apt metaphor is Disneyland rides. When you’re on the Pirates of the Caribbean ride, you are in the center of the experience. The experience surrounds you, engulfs you. Cannons roar. Water sprays. Fires rage. Wenches run. Pirates sing. And you are in the middle of it all. You can’t look away.

The “inside looking out” notion is key to understanding VR. For instance, it’s one of the reasons we no longer talk about having a camera in VR, because the very notion of a camera harkens back to an “outside looking in” perspective, with a window on the world. Instead, we talk about the person in VR — a person who can (and often will) look in every direction, the person who is completely immersed in the experience, and the person who can’t escape the experience without physically removing their headset!

Posted in Computers and Internet, Game Programming, VR | Leave a comment

Package Perfect

Recently I needed to package up an Unreal build for distribution. You can do this from the Unreal Editor v4.6 by selecting File->Package Project. However, I wanted to automatically create packages on a build machine without human intervention. That meant I needed to find a command I could execute in a script. Skipping to the hard won result, here’s the wooly command line I ended up with:

.\Engine\Build\BatchFiles\RunUAT.bat -verbose BuildCookRun -nocompileeditor -nop4 -project=MyProject.uproject -cook -allmaps -CrashReporter -stage -archive -archivedirectory=c:\Package -package -WindowsNoEditor -clientconfig=Shipping -ue4exe=UE4Editor-Cmd.exe -clean -pak -prereqs -targetplatform=Win64 -build -utf8output

Over twenty command line parameters. How did I figure that all out?

First I searched on the web for “Unreal command line package.” That led me to a promising page, so I tried the recommended command line there. However, when I compared my output with the output generated by the in-editor packaging step, not only were most of the files quite different, there were some files that were in one place and not the other. No dice.

Time to think like a software engineer.

Unreal distributes source code for their engine and editor. So I searched the code for the word archivedirectory (one of the parameters mentioned at the link above), which led me to .\Engine\Source\Editor\…\MainFrameActions.cpp. It has a line that starts with

FString CommandLine = ...


I set a breakpoint on that line in Visual Studio, started up the Unreal Editor, attached to the Unreal Editor from Visual Studio (Debug->Attach to Process), and then selected File->Package Project->Win64 in UE. Breakpoint hit! From there it was simple to copy the actual CommandLine value that UE uses to a batch file and tweak path names as needed.


  • I repeated this process a few times, tweaking the settings at Packaging Project->Packaging Settings so I could extract the various command line parameters that can be configured in the editor.
  • The –project setting must be the fully qualified path name
  • For shipping builds, use –clientconfig=Shipping. For development builds, use –clientconfig=Development. I didn’t try creating a Test build, but that would be an interesting experiment, since you can’t package test builds from inside the editor.
  • clean ensure a full build is done, –build builds code, –cook builds content, and –pak puts the content in a single pak file
  • The only platform I was targeting was 64-bit Windows, so you’ll need to validate the targetplatform parameter for other platforms


Posted in C++, Computers and Internet, Game Programming | Leave a comment