Monday, October 31, 2011

Auto-Wiring EventAggregator Subscription in Caliburn.Micro

 

Just wanted to make a quick note about how to get auto-wiring of the EventAggregator subscription up and running for Caliburn.Micro. What I want to accomplish is to avoid having to write this:

CaliburnMicro_AutoEA_1

… and instead make this "just happen" when a type implements IHandle. And as you can see from the code above, the IoC I use here is MEF.

So I haven't used MEF before, but I found this post ("Introduction to InterceptingCatalog – Part I") by Piotr Włodek and figured that with a little bit of tweaking this should work.

This code relies on the MEFContrib project up on CodePlex/GitHub, so if you haven't already downloaded it you can get it from there or just NuGet-it into your project;

CaliburnMicro_AutoEA_2

To be able to get any class that implements IHandle to list itself as a subscriber in the EventAggregator, we need to hook into the creation pipeline in MEF. And MEF hasn't any hooks that let us do this, but fortunately MEFContrib has and it's called an InterceptingCatalog.

The InterceptingCatalog takes two arguments; a ComposablePartCatalog and an InterceptionConfiguration. It's the InterceptionConfiguration that let's us provide an interceptor that can do the auto-wiring for us. But first, let's create the class that will do the interception - the EventSubscriptionsStrategy:

CaliburnMicro_AutoEA_3

This object creation strategy will be added to the MEF creation pipeline. This class will be called for every object resolved from MEF, but in this case we're only interested in those who implements the IHandle interface. So if the casting succeeds we now that this is class that will want to subscribe to events. So by using the Intercept method from the IExportedValueInterceptor interface, we can tell the EventAggregator that this object is an event subscriber.

The only thing missing then, is to plug our EventSubscriptionStrategy into MEF;

CaliburnMicro_AutoEA_4

This is from the default AppBootstrapper from Caliburn.Micro with the changes I made to get the EventSubscriptionStragegy registered in MEF marked in red.

References

Caliburn.Micro: http://caliburnmicro.codeplex.com/ - This is a WPF/SL/WP7 framework along the same lines as PRISM from Microsoft Patterns & Practices. Only much smaller (in size, not necessarily feature set) and much more "opinionated".

MEF Contrib: http://mefcontrib.codeplex.com/ and https://github.com/mefcontrib - Open source extensions to the Managed Extensibility Framework (MEF). In other words; extending the extensibility with extensions…

Tuesday, August 30, 2011

Create & Boot VHD

This is just quick list for creating and booting from a Virtual Hard Disk (VHD) in Windows 7.

1a. Creating VHD from scratch


If you’re creating a VHD from scratch (that is not a child-disk based on another VHD) this is the commands you need to run from command prompt:
:\> diskpart

Microsoft DiskPart version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: xxxxxxxx


DISKPART> create vdisk file=[FILEPATH] type=expandable maximum 50000

  100 percent completed

DiskPart successfully created the virtual disk file.

DISKPART> exit

The ‘:\>’ means command prompt, typically it would be ‘c:\>’ or something similar, but the actual directory you’re in doesn’t matter for the command.

Running the command ‘Diskpart’ will start the DOS-utility that we’ll use for creating the VHD. When diskpart starts, the command prompt will change to ‘DISKPART>’. Now you can type the command ‘create vdisk’ to create the actual VHD.

The command has only two required arguments; ‘file’ and ‘maximum’. The ‘file’-argument specifies where to output the vhd and the name of the vhd-file. So [FILEPATH] in the example above will typically be ‘D:\VHD\MyNewVhd.vhd’.

The ‘maximum’ argument specifies the size of the VHD in megabytes. You can choose between to types of disks (the ‘type’ argument); either fixed, meaning that the VHD file will be created with the size specified by the ‘maximum’ argument, or expandable, which means it will only be as big as the data on the disk requires but not larger than ‘maximum’. The default is fixed and if you have lots of space available it’s the recommended setting as it’s a bit faster than expandable disks. But on my laptop I do not have unlimited storage, so here I’ll go with the expandable option and setting the maximum file size to about 50 GB. It’s also a bit cheaper to do backups of smaller files, so expandable has it’s advantage there.

1b. Creating a differencing VHD


If you already have a base-VHD that you want to use as a parent-disk, this is the commands you need to run from command prompt:

:\> diskpart

Microsoft DiskPart version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: xxxxxxxx


DISKPART> create vdisk file=[FILEPATH] parent=[PARENT_FILEPATH]

100 percent completed

DiskPart successfully created the virtual disk file.

DISKPART> exit

As with the 1a) option above, the [FILEPATH] specifies the path and name of the disk to create. The ‘parent’ argument should be pretty obvious and [PARENT_FILEPATH] is the fully qualified name of the existing VHD you want to use as base-image.

Note that you cannot specify ‘maximum’ or ‘type’ as arguments for a differencing disk because the size of the child disk is set from the parent. It’s also possible to merge a diff-disk with it’s parent at a later point, to create a new VHD.

Remember to make your parent-disk read-only before you use it for differencing disk. Failing to do so and then accidentally starting up or booting directly in to your parent VHD, will render your differencing disks useless (and yes; I learned that the hard way).

Another gotcha to be aware of; if you want to boot in to the new differencing disk, it needs to be located on the same disk volume as the parent disk. They can be in different folders, but they cannot reside on another volume – not even if the volumes is on the same physical disk.

2. Boot it up!


When the VHD is ready to use, issue these commands to add them to your boot menu;
:\>bcdedit /copy {current} /d “My virtual boot entry”

The entry was successfully copied to {df399c86-f723-11df-85b6-8d1c50594e14}.

:\>bcdedit /set {df399c86-f723-11df-85b6-8d1c50594e14} device vhd=[locate]\Path\To\Disk.vhd

The operation completed successfully.

:\>bcdedit /set {#GUID#} osdevice vhd=[locate]\Path\To\Disk.vhd

The operation completed successfully.

:\>bcdedit /set {#GUID#} detecthal on

The operation completed successfully.

If you run the ‘bcdedit’ command without any arguments, you should be seeing your new boot entry at the bottom. And it should look something like this;

Windows Boot Loader
-------------------
identifier              {df399c86-f723-11df-85b6-8d1c50594e14}
device                  vhd=[locate]\Path\To\Disk.vhd
path                    \Windows\system32\winload.exe
description             My virtual boot entry
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {df399c79-f723-11df-85b6-8d1c50594e14}
recoveryenabled         Yes
osdevice                vhd=[locate]\Path\To\Disk.vhd
systemroot              \Windows
resumeobject            {df399c77-f723-11df-85b6-8d1c50594e14}
nx                      OptIn
detecthal               Yes


The first command, ‘bcdedit /copy’ will copy the default boot entry and create a new with the name specified by the /d argument. Then you’ll use the /set argument to modify the new entry. You’ll need to copy the id that will be displayed after the initial copy command, and input this as the first argument for the /set command.

There’s 3 things that need to be set; the device, the osdevice and the detecthal. The first to are similar and takes the path to the VHD you want to boot from as input. Note the ‘[LOCATE]’ syntax in the path; this will tell the boot manager to figure out which drive to locate the VHD on. So instead of ‘vhd=d:\path\to\disk.vhd’, you  need to enter ‘vhd=[locate]\path\to\disk.vhd’.

A little tip if you have spaces in the path or filename for the VHD; surround the path with apostrophes (‘).

The last /set command will give some instructions to the kernel to detect certain hardware information (HAL = Hardware Abstraction Layer), which is needed on some x86-based system.
And that’s it; Ready to boot!

Resources


In some of my earlier posts I wrote a bit about how to compact VHDs, how to automate Windows install on VHDs and some pros and cons with virtual machines.

Also, David Loongnecker has some good tips in his blog post Tips for Booting/Using VHDs in Windows 7.

Thursday, August 4, 2011

Compact virtual space

Keeping a virtual machine tidy will make it run faster and the VHD file itself smaller. Here’s a little list of things you can do to tidy it up a bit.

The usual suspects


First things to do is what you’ll do on any machine – virtual or not – to keep things as optimal as possible; The usual maintenance jobs includes deleting temporary files, emptying the recycle bin, cleaning up the registry, etc. I’ve found Glary Utilities (links at the end of this blog post) to be a good tool for this. Just install the free version and run the ‘Scan for issues’ under ‘1-click maintenance’.

If this is a fresh VHD which haven’t been used much you’ll probably won’t gain much from the usual housekeeping, but defragmenting and checking the disk (chkdsk) and Windows system files (sfc /scannow) seldom hurts.

Shrink wrap


To shrink the size of the VHD file you can compact the disk, but before you do that you need to pre-compact it. Compacting the disk is an operation you’ll do on the VHD-file, while pre-compacting is something you’ll do on the running virtual machine to make the compacting operation as effective as possible.

To pre-compact the VHD you need to run the precompact.exe which you can find on an ISO in the Virtual PC install directory (on my box the precompact.iso is in the folder c:\program files (x86)\windows virtual pc\integration components, but the exact location will vary depending on your OS and Virtual PC version).

precompact.exe must be run inside the virtual machine. You can either boot into it or fire it up in Virtual PC. Once you’re running the virtual machine you need to open the command line and navigate to the folder where that precompact.exe resides. Make sure you’re running with administrator privileges and run the following command:

:\> precompact –Silent –SetDisks:C

The last parameter specifies which disks to pre-compact and if not specified it will pre-compact all disks. In my case that wouldn’t be very wise, since I also have access to the host partition from my virtual machines.

When pre-compacting is done (can take quite some time depending on the size of your disk(s)), shut down the virtual machine.

Now it’s time for the actual compact process, so from your host OS fire up the command line and start the disk part utility;

:\> diskpart

When running the diskpart, enter the following commands (assuming the VHD file is named ‘parent.vhd’ and is in a folder called ‘vhd’ on partition ‘d’);

DISKPART> select vdisk file=”d:\vhd\parent.vhd”
DISKPART> attach vdisk readonly
DISKPART> compact vdisk
DISKPART> detach vdisk
DISKPART> exit

And that’s about it. You should now have a small and fast virtual machine (everything’s relative, right?)

Resources


Glary Utilities – Optimization software for Windows. Comes in two flavors; a free version for the basic optimization that’ll be good enough for most users and a paid version with more advanced tools.

Thursday, May 26, 2011

Installing Windows is boring

So why not automate it?
automatic-for-the-people-by-rem
I’m a big fan of virtual machines and especially booting from VHD natively in Windows 7 (as you might have guesed from my previous post).

On those virtual machines I run Windows 7 for the most part. Creating new VHD is pretty easy, but installing the OS and everything you need is a tedious task.

One way to solve this is to create a parent VHD with Windows 7 and then create child VHD based on this one. This is what I do for the most part, but sometimes I just need a fresh install of Windows 7.

I could off course do this by creating a blank VHD, boot into it and install Windows 7. But where’s the fun in that? Everything boring must be automated, so here’s the way to make your life just a little less boring. 
  1. Grab your copy of Windows 7 and extract/copy the content of the install disk into a local directory (if it’s a ISO file, use a tool like 7-zip). For exemplification I’ll use ‘d:\installs\win7’ as the directory containing the extracted Win7.
  2. Download the ISO Windows Automated Installation Kit (AIK) for Windows 7. As the name implies, this one is needed for automating the installation of Win7.
  3. Extract the AIK files from the downloaded ISO file (or burn it to disk) and install it.
  4. Download a neat little tool called WIM2VHD (which stands for Windows Image to Virtual Hard Disk), which is the tool that will actually do the automation for us. 
The WIM2VHD download is a Windows Script File (.wsf), which you will run after you’ve found out the correct SKU on your Windows Install Media (WIM). A Windows 7 installation disk may contain one or more versions (or stock-keeping units a.k.a. SKUs), e.g. Home, Premium, and Ultimate. To be able to install from the installation source extracted to ‘d:\install\win7’, the automation tool needs to know which version you intend to install. And for that you need a tool called ImageX, which came with the AIK you just installed.
  1. Go to the ‘tools’ folder in the AIK install folder (defaults to ‘c:\program files\windows aik\tools’)
  2. Find the appropriate version of the ImageX (if you’re running on a 32-bit OS that would be in the ‘x86’-folder, for 64-bit it’s the ‘ia64’) and copy it to the same folder as the WIM2VHD script.
  3. Run ImageX to find out which SKU to install
  4. Then run the WIM2VHD script with the the path to the WIM and the desired SKU as params;
cscript wim2vhd.wsf /wim:d:\installs\win7 \sources\install.wim /sku:ultimate

The script will then start making you a brand new VHD in the same folder you’re running the script from (alternatively you can add a /vhd param to the command above to specify a path to the output vhd).

Some minutes later you’ll have a (almost) pre-installed VHD with Windows 7.