Windows Special Folder enum

Desktop : C:\Users\<user>\Desktop
Programs : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
MyDocuments : C:\Users\<user>\Documents
Personal : C:\Users\<user>\Documents
Favorites : C:\Users\<user>\Favorites
Startup : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
Recent : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Recent
SendTo : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\SendTo
StartMenu : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu
MyMusic : C:\Users\<user>\Music
MyVideos : C:\Users\<user>\Videos
DesktopDirectory : C:\Users\<user>\Desktop
MyComputer :
NetworkShortcuts : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Network Shortcuts
Fonts : C:\Windows\Fonts
Templates : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Templates
CommonStartMenu : C:\ProgramData\Microsoft\Windows\Start Menu
CommonPrograms : C:\ProgramData\Microsoft\Windows\Start Menu\Programs
CommonStartup : C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
CommonDesktopDirectory : C:\Users\Public\Desktop
ApplicationData : C:\Users\<user>\AppData\Roaming
PrinterShortcuts : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Printer Shortcuts
LocalApplicationData : C:\Users\<user>\AppData\Local
InternetCache : C:\Users\<user>\AppData\Local\Microsoft\Windows\INetCache
Cookies : C:\Users\<user>\AppData\Local\Microsoft\Windows\INetCookies
History : C:\Users\<user>\AppData\Local\Microsoft\Windows\History
CommonApplicationData : C:\ProgramData
Windows : C:\Windows
System : C:\Windows\system32
ProgramFiles : C:\Program Files (x86)
MyPictures : C:\Users\<user>\Pictures
UserProfile : C:\Users\<user>
SystemX86 : C:\Windows\SysWOW64
ProgramFilesX86 : C:\Program Files (x86)
CommonProgramFiles : C:\Program Files (x86)\Common Files
CommonProgramFilesX86 : C:\Program Files (x86)\Common Files
CommonTemplates : C:\ProgramData\Microsoft\Windows\Templates
CommonDocuments : C:\Users\Public\Documents
CommonAdminTools : C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools
AdminTools : C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools
CommonMusic : C:\Users\Public\Music
CommonPictures : C:\Users\Public\Pictures
CommonVideos : C:\Users\Public\Videos
Resources : C:\Windows\resources
LocalizedResources :
CommonOemLinks :
CDBurning : C:\Users\<user>\AppData\Local\Microsoft\Windows\Burn\Burn

code to generate


class Program
        static void Main(string[] args)
            string[] specialPaths = Enum.GetNames(typeof(Environment.SpecialFolder));
            foreach (string special in specialPaths)
                Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), special);
                string path = Environment.GetFolderPath(specialFolder);
                Console.WriteLine( special + " : " + path );

Zombie project collections in TFS after server migration and split

grr argh.

I recently had to move a project collection from one server to another with the aid of MS support. I did this by restoring backups and using TFSconfig to remap the databases.

One of the steps we did was to delete some rows from the configuration database that referred to the other project collections that were left behind

FROM [Tfs_Configuration].[dbo].[tbl_ServiceHost]

but I noticed that the project collections would appear in the list of available collections in the server.

This also made the TFS4Jira plugin fail to reconfigure as it was throwing an error about one of the deleted collections.

I managed to fix these issues by removing the rows for the old collections

FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource]

with the following query.


FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource]

where ResourceType = ‘26338D9E-D437-44AA-91F2-55880A328B54’

and Identifier != ‘C39F7AAF-F135-468F-9E10-41341D27CC3A’

the identifier was the project collection that I wanted to keep and the resource type mapped to a team project collection.

you can look up the project collections with the following query.


FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource] cr

INNER JOIN [Tfs_Configuration].[dbo].tbl_CatalogResourceType crt

ON cr.ResourceType = crt.Identifier

WHERE crt.DisplayName = ‘Team Project Collection’

Robohelp 8 command line build failing

Today I was faced with the dreaded :-

EXEC : error : Failed to scan all the project files. Please use RoboHelp to recover the project. [E:\Builds\40\100\BuildType\TFSBuild.proj]

EXEC : Unexpected error : Failed to prepare single source data for RHCL. Please try to compile it in RoboHTML. [E:\Builds\40\100\BuildType\TFSBuild.proj]

This basically means that the structure of the robohelp project is damaged in some way and the robohelp command line has given up. Building it as it says in the editor makes it work again.

I did a diff of the folders and noticed that the editor had recreated some .fpj files in some empty folders (they had just been deleted). Going up a level and looking in that folders fpj file showed me that the folders were still referenced, so I deleted the extra folder tags and checked that file back in to get it working again.

Build machine bundles.

Rob Mensching (owner of the Wix opensource project) just suggested making a build bundle for preparing build machines for the wix toolset.

My initial reaction was that it seemed overkill as you can just check in most pre-requisites these days. But as I thought about it it is remarkably elegant.

Build machine preparation would be trivial for the uninitiated.

The prerequisites would be documented in code and locked down.

You could implement an auto-update mechanism that would allow you to silently and remotely update your build farm.

Legacy build machines would no longer need to be archived, you could just store the build installer.

TFS and Visual Studio2012

When I made a new build VM with Visual studio 2012 tools on it today I found that my builds would not work.

After some poking about in the TFS build targets I found out that a property called SourcesSubdirectory had changed from sources to src. this was showing up in the generated workspace and was foxing my builds.

For some reason we were creating a global property called sourceroot that had a hardcoded “sources” at the end.

I swapped the whole sourceroot property for the built in SolutionRoot property which is the root of the sources in a TFS build (its name stems from desktop builds and is confusing in this context).

Shortcuts as tiles on windows 8

If you install shortcuts to the start menu they will appear as a tile on windows 8 using the shortcut’s icon and title. Some of the shortcuts may be on the main windows 8 start menu and some may be hidden under All Apps (right click anywhere that isn’t a tile to see the all apps option).

You cannot install a ‘start menu’ / metro application from the windows installer, they need to come from the windows store or certain versions of windows allow enterprise admins to sideload to that location after jumping through lots of security hoops.

I did some testing and it looks like you can control which shortcuts appear on the main start menu with shortcut properties, otherwise windows will decide on its own which appear on the main menu.

System.AppUserModel.StartPinOption ( allows you to force your shortcut not to appear on the main start menu. There also seems to be a bug on windows 7 where you get a pop up warning dialogue if you use these properties by name so you have to use the guid format.


I don’t see an option anywhere to force your shortcut to be displayed in the start menu.

Example from my test:-

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="">
 <Product Id="*" Name="W8Shortcuts" Language="1033" Version="" Manufacturer="wyrdsoft" UpgradeCode="93a11f97-8a67-43f9-8444-0e8654ec3809">
 <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
 <MediaTemplate EmbedCab="yes" />

<Feature Id="ProductFeature" Title="W8Shortcuts" Level="1">
 <ComponentGroupRef Id="ProductComponents" />

 <Icon Id="ProductIcon.exe" SourceFile="Product.ico" />

 <Directory Id="TARGETDIR" Name="SourceDir">
 <Directory Id="ProgramFilesFolder">
 <Directory Id="INSTALLDIR" Name="bob">
 <File Source="..\TheApplication\bin\Debug\TheApplication.exe"/>
 <Directory Id="ProgramMenuFolder">
 <Directory Id="CompanyShortcutDir" Name="WyrdSoft">
 <!-- Shortcut menu name doesn't change between SPs. -->
 <Directory Id="ProductShortcutDir" Name="ShortcutTest"/>


 <ComponentGroup Id="ProductComponents" >
 <ComponentRef Id="RemoveProductShortcutDir"/>
 <ComponentRef Id="ProductShortcut"/>
 <ComponentRef Id="RemoveCompanyShortcutDir"/>
 <ComponentRef Id="TheApplication.exe"/>


 <DirectoryRef Id="ProductShortcutDir">
 <!-- This registry key must be common to all installers that use this folder. -->
 <Component Id="RemoveProductShortcutDir">
 <RegistryValue Root="HKMU" Key="Software\company\ShortcutTest\Installer" Name="RemoveProductShortcutDir" Value="KeyPath" KeyPath="yes" Type="string" />
 <RemoveFolder Id="RemoveProductShortcutDir" On="uninstall"/>

<Component Id="ProductShortcut">
 <RegistryValue Root="HKMU" Key="Software\company\ShortcutTest\Installer" Name="ProductShortcut" Value="KeyPath" KeyPath="yes" Type="string" />
 <Shortcut Id="ProductShortcut" Name="The Application" Description="The application." IconIndex="0" Icon="ProductIcon.exe" Target="[#TheApplication.exe]">
 <ShortcutProperty Key="System.AppUserModel.ID" Value="Company.TheApplication.exe" />
 <ShortcutProperty Key="{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 12" Value="1" />
 Name: System.AppUserModel.StartPinOption - PKEY_AppUserModel_StartPinOption
 Type: UInt32 - VT_UI4
 FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 12

 Note: Set this property on a shortcut to (1) prevent an application from being automatically pinned to Start screen upon installation; or
 (2) indicate that an item is programmatically added to launcher via user action (which implies automatically pin to Start and delete on unpin).

 Note: It has to be a guid to stop windows 7 throwing a warning dialogue.

 Note: that you must also set System.AppUserModel.ID first or the property will not be used.


 <DirectoryRef Id="CompanyShortcutDir">
 <Component Id="RemoveCompanyShortcutDir">
 <RegistryValue Root="HKMU" Key="Software\Company\Installer" Name="RemoveCompanyShortcutDir" Value="KeyPath" KeyPath="yes" Type="string" />
 <RemoveFolder Id="RemoveCompanyShortcutDir" On="uninstall"/>

Parsing formulas in c#

For the first part of my first windows phone application (a set of RPG utilities) I decided to create a way of managing dice rolls. While this seems to be something that there are several of in the windows store nothing gave me the basic functionality that I wanted.

  • Access to basic RPG dice d20, d6 etc.
  • The ability to enter more complex rolls 5d6+6
  • A way of storing custom sets of dice for later.

So I quickly did the first one with some buttons and the built in random number generator, easy.

Now entering multiple dice and dice formula was clearly going to be a bit tricky. So I got stuck in and bashed out some code that did cunning replacements with regular expressions which fulfilled the basic criteria. It wasn’t pretty but it worked to a point, and when I tried to implement brackets I realized I was doing something wrong.

So I started to look for a simple way to parse generic formulae, most of solutions I found seem to be pointing at expensive maths libraries which I didn’t want to pay for just to give away in a free application.

Then I found out about the shunting yard algorithm which converts from infix (normal mathematical notation) to RPN which seemed ideal for my needs as I could expand it to do dice tricks (critical rolls, or openended roll up for instance).

I took inspiration from this article and added in dice resolution.

To get my dice parsing working I created a separate solution and added a test project to make sure I had covered all the formulas that I wanted to handle.

Next up I will add support for dice tricks.