Category Archives: Technology

Windows 10 upgrade survival guide

So I’ve been through the process to upgrade 3 machines (2 laptops and one desktop so far) to Windows 10 with a 33% success rate… yeah, I know that does not sound that promising. The other 66% I managed to fix with ‘resets’ which is basically a fresh install. In the end that comes to (technically) 99%. There are a few things that isn’t 100%… (small) things that are still causing some headaches – this guide is not about them.

So I decided to create this post to help others with the process. This will not be a all-out guide to upgrading because I’m sure I didn’t experience ALL the troubles you can have while upgrading to Windows 10.

Before the install

First tip I have is to rather use the Windows 10 Media creation tool to download the full ISO ( https://www.microsoft.com/en-us/software-download/windows10 ). The reasons for this are simply because then you have control over the download and if that fails the actual upgrade process does not fail at the same time. Secondly, you can then use the same ISO image to upgrade multiple machines without having to download the same ‘stuff’ multiple times.

Second tip is to prepare your machine for the upgrade by backing up (always a good idea) and cleaning any unused stuff – like uninstall applications which you really don’t use anymore as all applications whether you use it or not has to go through the upgrade process (be part of it) and can increase the duration time of the upgrade. The same applies to any unused hardware and drivers. Just get rid of them before you start. Unplug any external USB flash/hard drives. The Windows 10 upgrade process also checks for compatibility in case you missed something that is not compatible. Also, save of make a copy (or even a screenshot) of any saved passwords (e.g. those that are stored in your browser).

Thirdly it is useful to have a backup of all your drivers (yes, even those that you don’t even have the original disk for anymore!). I use a simple too like DriverBackup! ( http://sourceforge.net/projects/drvback/ ) but you can use any similar tool. In some cases Windows 8.x drivers should be compatible with Windows 10 (but don’t quote me on that). If for some reason Windows 10 did not recognize your hardware after the upgrade you can try to point device manager’s check for updated drivers to this driver backup directory.

4th’ly check for any outstanding Windows updates (yes the upgrade tool can also do this but it is better that you do this manually and you get to choose what/when/how this gets installed).

Lastly uninstall your anti-virus software (yes, that thing that hogs your machine worse than a virus itself). Some (possibly all) anti-virus software have been known to cause problems while doing Windows upgrades. You can re-install your anti-virus software after the upgrade if it is supported (might need to be upgraded to a Windows 10 compatible version in any case).

The Install

All of this and you haven’t even started the upgrade yet! phew… hehe

To start the upgrade process you can either create a DVD from the ISO using you favorite DVD burning tool (even Windows explorer in Windows 7 have an option to burn to DVD) or you can use a tool to open the ISO like a zip file (e.g. 7-zip which is free – http://www.7-zip.org/ ) and extract all the files somewhere on your hard drive. Once this is done simply run the Setup.exe in the root directory of this DVD/extracted directory. At this stage choose the option NOT to ‘also download updates’ (since you already did that during tip number 4).

The rest of the install process is mostly automated – with multiple reboots… crashes… bluescreens… just joking. If it does crash it should roll back and restore the previous version of Windows (this I’ve experienced a few times with the Insider previews so it does work). Just sit back and relax… right…

Post installation

Post the installation you are given some options to choose privacy options. For my taste I choose to disable most of them (like the typing and advertising settings which are enabled by default). Also, the Wireless Sense stuff I also disable (old habits of not trusting others…). When prompted for default apps you can choose to customize and then un-tick the ones presented as replacements. In my opinion the default should be to keep you existing default apps (like browser, music player etc) and have the new Microsoft alternatives as suggestions – not forced down you computing throat.

Wrap up

Ok, so once the setup/installation part is done and you are back at your desktop there are a couple of things to check and make sure all is happy in Windows 10 land. One of the first things I always check after such an upgrade is that all hardware (drivers) are properly installed. You can check this (in Windows 10) by right clicking on the new Start button (yes right-click on the start button actually does something useful – if you come from Windows 7 world) and choose ‘Device Manager’. Check for any yellow/red warning triangles (usually it should be very obvious as the tree nodes will be expanded by default showing the problem components). At this stage you can right click of the problematic component/tree node and choose ‘Update Driver Software’.

Try the online search option first as that ‘should’ get the latest available driver if any exists (and the device has been recognized). If it doesn’t work to ‘fix’ the device then try the same procedure again but this time choose the ‘Browse my computer…’ option and specify the driver backup directory as created in tip no. 3. (or if you happen to have the original disk that came with the device… what?? anyone keep those disks?? hehe). If this does not work try searching the manufacturer’s web site for updated drivers. Chances are that they won’t have Windows 10 drivers yet as it takes time to create and certify those drivers. In some cases Windows 8.1 drives ‘may’ work but… don’t quote me on that either. If all of this does not work then.. it just wasn’t meant to be… for now 🙂

Troubleshooting (Update)

If for some reason after this upgrade you experience problems like hardware devices bot working (even if drivers are installed and seems to be ok) or you get Blue screens of death (yes, they’re still blue) you can try to do a Windows ‘Reset’. This is rather destructive as far as your applications goes but at least your ‘Data’ files stay in tack.

If you can get into Windows (in case you don’t have Blue screen of death on login) you can go to Settings -> Recovery and Choose the ‘Reset this PC’ option. Choose to keep your files… unless you don’t want them anymore…

Alternatively if for some reason can can’t do this from within Windows itself make/obtain a bootable image (DVD or of your machine supports it – USB) and boot up from it. After selecting the languages and stuff on the first screen you will see a ‘Repair’ option on the second screen you get. From there you can select ‘Troubleshooting’ (or something like that since I don’t have that screen open now) and then ‘Reset this PC’. Remember to choose ‘Keep my files’. After that it will start (re)installing just like a full installation, multiple reboots etc. and eventually back at the login screen. At that point you’ll have a fairly ‘blank’ Windows installation with nothing but the default Windows applications installed. Your files will still be there but any applications you use that didn’t came with Windows itself will need to be reinstalled. Sometimes this actually might be a good thing to get rid of all the crap one has installed over the years…

Conclusion

All-in-all I think Windows 10 does have more positives than (drumroll) negatives. There are things I really don’t like about it but then there are some I do (like). Once you get it up and running it does seem to be worth the trouble. Happy Windows 10ing… (but I will miss my Windows 7)

VirtualBox 5 released

Just a heads-up. Oracle’s VirtualBox 5.0 has been released.

Head over to https://www.virtualbox.org/ and grab it while it’s still hot.

Updating VLC plug-in in FireFox with 64-bit VLC installed

I discovered this issue as part of checking that all plug-ins in Firefox is up to date (thanks to Adobe’s security mess). The VLC plug-in was listed as outdated so I updated VLC from their web site – the 64-bit version as that is what I use.

Checking Firefox again (plugincheck) I noticed VLC was still listed as outdated with the version unchanged. Thanks to Google I found an article that shows how to get the path of all Firefox plug-ins (about:plugins). This gave me the path C:\Program Files (x86)\VideoLAN\VLC\npvlc.dll . Fortunately VLC provides a plain zip/7zip download of their apps (http://www.videolan.org/vlc/download-windows.html) which you can use to simply copy the files over the old version.

Well, that is one way to skin a… fix a plug-in I mean… 🙂

Windows Update error code list

Just as a reference since I’m also always looking for these myself(pulling my already missing hair out). A list of Windows Update error codes.

https://support.microsoft.com/en-us/kb/938205

One small note. The best one is 0x80240FFF… (WU_E_UNEXPECTED An operation failed due to reasons not covered by another error code). They should just have changed the wording to be a slight bit more honest and say: ‘An error occurred and we haven’t got a clue what it is (as usual)’ 😉

Windows 10 upgrade blues

I’ve been the (un)lucky one that hit the issue where a number of my test VMs all fail to upgrade from build 10159 to 10162. Despite trying all those integrity scans (chkdsk c: /f /r /x) or cleanups (Disk cleanups with remove previous builds) it always failed at around 40%. This was happening on multiple machines (VMs) – some on VirtualBox and even one on Hyper-V.

Checking the setuperr.log file it always seemed the following line was the culprit:

Error      [0x018046] CSI    0000013b (F) Failed execution of queue item Installer: ServiceModelReg Installer ({79675b3f-2054-4efd-aa9d-e1830916be47}) with HRESULT HRESULT_FROM_WIN32(52).  Failure will not be ignored: A rollback will be initiated after all the operations in the installer queue are completed; installer is reliable[gle=0x80004005]

Unfortunately the Internet (Google and Bing) wasn’t kind finding any help on this. Then out of desperation I looked at some of the ‘earlier’ errors which seemed to be ignored and that is all related tp IIS App pool (since I have IIS and Visual Studio 2015 RC installed). I even tried uninstalling Visual Studio on one instance but still no luck. In a moment of almost pure madness I launched the ‘Windows Features’ from Control panel and simply removed IIS from the current installation (including HTTP Activation from the .Net installs). It does not make sense that Microsoft would break their upgrade process due to one of their own technologies but there you have it!

Rerun the upgrade again and… whola it works.

Update: I’ve now confirmed this on 3 different machines. 2 VirtualBox VMs and one Hyper-V VM.

Update 2: Seems the problem is more about having both .Net 3.x and 4.x HttpActivation features on at the same time – http://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_install/bug-upgrade-81-to-windows-build-10162-fails-if/228b1433-823e-4cd4-90da-72be01c592fb?auth=1

 

Windows 10 in VirtualBox video driver crashes (fix)

I’ve been running a copy (actually 2) of Windows 10 insider preview (build 130 currently) and regularly experience the issue where the video driver provided by VirtualBox crashes and the resolution drops to a standard size using the default Windows 10 display driver. The issue is Oracle (makers of VirtualBox) has not created a new video driver for Windows 10 yet – it is still the default one for Windows 8.x so it probably hasn’t been tested and optimized properly for Windows 10.

To fix the video drive I used to restart the VM which then restores the video driver and restores the resolution prior to the crash. Fortunately I came across some forum posting about another issue I know about on Windows 8 on ATI GPUs where the mouse cursor becomes corrupt that suggests to simply go to Device Manager and disable and then enable the video driver itself to fix the problem. Turns out this also works for Windows 10 video driver crashes. Doing it should not ‘break’ anything since the video driver is in a crashed state anyway when you disable it. After enabling it again Windows 10 automatically restores the previous resolution and all is happy in Insider Preview land again…

Update: I found a way to automate this solution using PowerShell! Using device-management-powershell-cmdlets I created a script that disables and then re-enables the display driver. e.g.

Import-Module "C:\Program Files\Common Files\DeviceManagement\DeviceManagement.psd1"
$DisplayDevice = Get-Device | Where-Object -Property Name -like "VirtualBox Graphics Adapter for Windows 8*"
Disable-Device -TargetDevice $DisplayDevice
Enable-Device -TargetDevice $DisplayDevice

This is assuming you copied the downloaded module to “C:\Program Files\Common Files\DeviceManagement”

Update: I probably should say ‘Touch Wood’ but ever since I upgraded to VirtualBox 5.0 I haven’t had any Display driver crashes again (on Windows 10 build 10166)

Windows 10 guest in VirtualBox – better GPU driver support

Just a heads-up for anyone that might be having issues with display driver issues in VirtualBox. There is an updated (test version) of the VBoxGuestAdditions add-ons available. See the following thread:

https://forums.virtualbox.org/viewtopic.php?f=2&t=67654

Direct download link: https://www.virtualbox.org/download/testcase/VBoxGuestAdditions_4.3.27-99864.iso

In the thread they also make other suggestions like turning 3D acceleration off if you can’t do anything else.

Creating a Multi-instance self registering service

This is one of those things I’ve been wanting to do for a long time for my Event Scavenger pet project. Basically the requirement is this:

“Being able to have one executable (.exe) file that can be used multiple times for different service instances.”

It turns out it is not too hard to achieve this using C# and .Net 4.0 (might even work with older frameworks but haven’t tried it). It is an extension of my already improved self registering Windows Service extensions which make it possible to simply run the Service exe with a ‘-install’ command line parameter. With the latest additions a ‘named’ instance can also be specified. This means, in the Service Manager of Windows you can see the Service executable plus a command line parameter that makes it unique. It allows you to stop/start/manage it separately as an entity. This is exactly the same as how Microsoft BizTalk Server implements ‘Host Instances’.

Now lets get dirty with some code samples. The first code snippet shows (an example) part of main program.cs that handles the command like parameters.

string collectorName = "Default";		

if (args.Length > 0)
{                
  if (args[0].ToUpper() == "-INSTALL")
  {
              string serviceParameters = "";
    if (args.Length > 1)
    {
      collectorName = args[1];
                  serviceName = "Event Reaper - " + collectorName;
      displayName = "Event Reaper - " + collectorName;
                  serviceParameters = "\"-Collector:" + collectorName + "\"";
    }
    if (args.Length > 2)
      displayName = args[2];
    if (args.Length > 3)
      description = args[3];

    HenIT.Services.ServiceRegister.InstallService(
      System.Reflection.Assembly.GetExecutingAssembly().Location,
      serviceName,
      displayName,
      description,
                  serviceParameters);
    return;
  }
  else if (args[0].ToUpper() == "-UNINSTALL")
  {
    if (args.Length > 1)
    {
      collectorName = args[1];
                  serviceName = "Event Reaper - " + collectorName;
    }
    HenIT.Services.ServiceRegister.UnInstallService(
       System.Reflection.Assembly.GetExecutingAssembly().Location,
                 serviceName);
    return;
  }
  collectorName = HenIT.CommandLineUtils.GetCommand(args, "", "-Collector:");
}
if (collectorName.Length == 0)
  collectorName = Properties.Settings.Default.CollectorName;

ServiceBase[] servicesToRun;
servicesToRun = new ServiceBase[] 
{ 
  new EventReaperService() { CollectorName = collectorName }
};
ServiceBase.Run(servicesToRun);

All this section does is to check for the “-INSTALL” or “-UNINSTALL” parameters and then call the helper class that does the registration/unregistration. The Display name of the service instance is always prefixed with “Event Reaper – ” to grouped all instances visually together in Service manager.

InstallService

The ServiceRegister class only has two methods. InstallService is the first one and handles all the bits to gather login details, set properties and then register the service.

public static bool InstallService(string serviceExePath,
        string serviceName,
        string displayName,
        string description,
        string serviceParameters)
{
    bool success = false;
    try
    {
        string workingPath = System.IO.Path.GetDirectoryName(serviceExePath);
        string logPath = System.IO.Path.Combine(workingPath, "Install.log");
        ServiceStartMode startmode = ServiceStartMode.Automatic;
        ServiceAccount account = ServiceAccount.LocalService;
        string username = "";
        string password = "";
        bool delayedStart = true;

        InstallerForm installerForm = new InstallerForm();
        installerForm.StartType = ServiceStartMode.Automatic;
        installerForm.AccountType = ServiceAccount.User;
        installerForm.BringToFront();
        installerForm.TopMost = true;
        if (installerForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            startmode = installerForm.StartType;
            account = installerForm.AccountType;
            delayedStart = installerForm.DelayedStart;
            if (installerForm.AccountType == ServiceAccount.User)
            {
                username = installerForm.UserName;
                password = installerForm.Password;
            }


            Hashtable savedState = new Hashtable();
            ProjectInstallerForHelper myProjectInstaller = new ProjectInstallerForHelper(delayedStart);
            InstallContext myInstallContext = new InstallContext(logPath, new string[] { });
            myProjectInstaller.Context = myInstallContext;
            myProjectInstaller.ServiceName = serviceName;
            myProjectInstaller.DisplayName = displayName;
            myProjectInstaller.Description = description;
            myProjectInstaller.StartType = startmode;
            myProjectInstaller.Account = account;
            if (account == ServiceAccount.User)
            {
                myProjectInstaller.ServiceUsername = username;
                myProjectInstaller.ServicePassword = password;
            }
            myProjectInstaller.Context.Parameters["AssemblyPath"] = serviceExePath + " " + serviceParameters;

            myProjectInstaller.Install(savedState);
            success = true;
        }
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message, "Install service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
    }
    return success;
}

The class InstallerForm is simply a plain Windows Form to capture service properties like the username/password etc. I’m not showing its code here now. AssemblyPath is the actual property that Service manager use to launch the executable plus its parameters.

ProjectInstallerForHelper is an utility class that simply inherits from System.Configuration.Install.Installer. It looks like this:

internal class ProjectInstallerForHelper : System.Configuration.Install.Installer
{
    private ServiceProcessInstaller processInstaller;
    private System.ServiceProcess.ServiceInstaller serviceInstaller;

    public ProjectInstallerForHelper(bool delayedAutoStart = true)
    {
        processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new System.ServiceProcess.ServiceInstaller();
        serviceInstaller.DelayedAutoStart = delayedAutoStart;

        Installers.AddRange(new Installer[] {
                processInstaller,
                serviceInstaller});
    }

    #region Added properties
    public string ServiceName
    {
        get { return serviceInstaller.ServiceName; }
        set { serviceInstaller.ServiceName = value; }
    }
    public string DisplayName
    {
        get { return serviceInstaller.DisplayName; }
        set { serviceInstaller.DisplayName = value; }
    }
    public string Description
    {
        get { return serviceInstaller.Description; }
        set { serviceInstaller.Description = value; }
    }
    public ServiceStartMode StartType
    {
        get { return serviceInstaller.StartType; }
        set { serviceInstaller.StartType = value; }
    }
    public ServiceAccount Account
    {
        get { return processInstaller.Account; }
        set { processInstaller.Account = value; }
    }
    public string ServiceUsername
    {
        get { return processInstaller.Username; }
        set { processInstaller.Username = value; }
    }
    public string ServicePassword
    {
        get { return processInstaller.Password; }
        set { processInstaller.Password = value; }
    }
    #endregion
}

UnInstallService

This is essentially just the reverse of InstallService.

public static bool UnInstallService(string serviceExePath, string serviceName)
{
    bool success = false;
    try
    {
        ServiceController sc = new ServiceController(serviceName);
        if (sc == null)
        {
            System.Windows.Forms.MessageBox.Show("Service not installed or accessible!", "Stopping service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
            return true;
        }
        if (sc.Status == ServiceControllerStatus.Running || sc.Status == ServiceControllerStatus.Paused)
        {
            sc.Stop();
        }
    }
    catch (Exception ex)
    {
        if (!ex.Message.Contains("was not found on computer"))
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, "Stopping service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
        }
        else
            return true;
    }
    try
    {
        string workingPath = System.IO.Path.GetDirectoryName(serviceExePath);
        string logPath = System.IO.Path.Combine(workingPath, "Install.log");

        ServiceInstaller myServiceInstaller = new ServiceInstaller();
        InstallContext Context = new InstallContext(logPath, null);
        myServiceInstaller.Context = Context;
        myServiceInstaller.ServiceName = serviceName;
        myServiceInstaller.Uninstall(null);
        success = true;
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message, "Uninstall service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
    }
    return success;
}

Summary

And this is basically the whole thing that allows you to create a Windows Service in C# that can handle multiple instances. There are a few things to keep in mind like the fact that all instances share the same config file unless you make a physical copy of the exe and config file to another directory and register it from there. Using this you can multiple services using different config all running side by side not affecting each other (hopefully hehe)

Creating custom BizTalk Event View

This is not exactly ‘new’ technology but someone might find it useful. In recent Windows versions Microsoft enhanced the way the Event log work and function plus the way you can access it. The default Event Viewer inside Windows support creating ‘Views’ with which you can filter events based on your needs. If you know your XML syntax you can create some nice views for yourself. I created one for filtering all BizTalk related events that can simply be imported and then used as is. The XML looks like this:

<ViewerConfig>
<QueryConfig>
<QueryParams>
  <UserQuery /> 
  </QueryParams>
<QueryNode>
  <Name>BizTalk Server</Name> 
<QueryList>
<Query Id="0" Path="Application">
  <Select Path="Application">*[System[Provider[@Name='BizTalk Server']]]</Select> 
  <Select Path="Application">*[System[Provider[@Name='BizTalk Server Deployment']]]</Select> 
  <Select Path="Application">*[System[Provider[@Name='ENTSSO']]]</Select> 
  </Query>
  </QueryList>
  </QueryNode>
  </QueryConfig>
<ResultsConfig>
<Columns>
  <Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">120</Column> 
  <Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column> 
  <Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">170</Column> 
  <Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">99</Column> 
  <Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">80</Column> 
  <Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">80</Column> 
  <Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column> 
  <Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column> 
  <Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column> 
  <Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column> 
  <Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column> 
  <Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column> 
  <Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column> 
  <Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column> 
  <Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column> 
  <Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column> 
  <Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column> 
  <Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column> 
  <Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column> 
  <Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column> 
  </Columns>
  </ResultsConfig>
  </ViewerConfig>

To use simply copy/past into an XML file and use the ‘Import Custom View…’ context menu option in the standard Event Log Viewer of Windows.

Of course, if you want a proper Event View solution over a whole group of servers use my Event Scavenger tool 😉

Windows Command Centre

A few years ago I created a quick utility to simply bring together all the various configuration tools that are included inside Windows itself. The problem is that there are actually all these built-in tools and utilities but finding them sometimes require you to search or discover them by accident. The tool I created simply provides an easy way to get to a lot of them. Even in Windows 7 not everything is located in one place – especially the more ‘advanced’, older or legacy tools – e.g. ODBC settings. Additionally I added something simple to simply ‘list’ the installed .Net versions as well.

A quick summary of what it contains:

System

Control panel
Manage computer
System config
Registry editor
Performance monitor
Scheduled tasks
Locale

Regional settings
Date and time

.Net

List versions
Disable Explorer GAC view

Hardware

Device manager
Install hardware
Remove hardware
Power options
Disk management
Removable storage
Settings

Keyboard
Mouse
Display
Sound
Printer

Software

Add & remove programs
Default programs
Windows components

Services

Services
IISAdmin
Component services
ODBC

Security

Security centre
Firewall settings
User accounts
Policy
Local security settings

Connections

Network connections
Create share
Shared folders
Map network drive
Disconnect network drive
Internet options

Looks

Taskbar properties
Fonts
Folder options
Display themes

I’ve now simple recompiled the utility and created a very simple installer for it (one for x86 and one for x64)

x86 – https://dl.dropbox.com/u/20983/WindowsCommandCentreSetup.msi

x64 – https://dl.dropbox.com/u/20983/WindowsCommandCentreSetupx64.msi

I’ve tested it on Windows 7 and it use to work on Vista/XP as well. Unfortunately I cannot guarantee that it will work properly on Windows 8 if at all. All it requires is the base .Net 2.0 framework to work.