Using MSBuild Community Tasks XmlRead and XmlUpdate

Importing the MSBuild Community Tasks into a Visual Studio project can make difficult tasks easy. In my scenario I wanted to hook into the BeforeBuild target so I could modify the defaultVersion attribute in a combres.xml before TeamCity created a Release build.

Firstly you need to import the MSBuild Community Tasks (MSBCT) into the .csproj. And in my scenario I didn’t want other developers to have to install MSBCT so I conditionally import on non-debug builds.

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="'$(Configuration)' != 'Debug'" />

Then I wanted to prove the concept so I used XmlRead first. I had to workout the XPath first, so once that was defined I dropped that into the XPath attribute:

<XmlRead XmlFileName="App_Data\combres.xml" XPath="//*[local-name()='resourceSets']/@defaultVersion">             
  <Output TaskParameter="Value" PropertyName="combresDefaultValue" />
</XmlRead>

Running from the command line:

msbuild.exe project.csproj /t:BeforeBuild /p:configuraton=Release

I could see the output of XmlRead on the command line.

Switching to XmlUpdate now made sense. So I commented out the XmlRead and added

<XmlUpdate XPath="//*[local-name()='resourceSets']/@defaultVersion"
             XmlFileName="App_Data\combres.xml"
             Value="$([System.DateTime]::Now.ToString(`yyyyMMddHHmmss`))" />

Now the combres.xml file has it’s defaultVersion attibute modified for every Release build.

<resourceSets url="~/combres.axd" defaultVersion="20130228144417" ...>

Christmas Laser Lights – 2012

I recently purchased a Christmas themed laser light to augment my LED christmas lights. I wanted something snazzy and with a unique look. A laser light show was perfect. It cost roughly AUD$68 + $12 postage.

Take a look at the video, I think this will explain how it looks better than I can describe with words.

Click to see Laser in action (Video)

Pros:

  • It came with a remote to turn it on/off, change colours, change mode. (Though I doubt I will use the remote much).
  • Also included was a small (10cm) tripod.
  • It’s light in weight, and very powerful (pointing at trees 50-100m away you could see the laser still).

Cons:

  • The “XMAS” wording is printed backwards (hoping to open the box and fix).
  • It’s not waterproof, so you need to bring it in of a night.

Windows 8 Store App – Page Inspector aka DOM Explorer

I recently had a frustration trying to inspect the DOM while writing a Windows 8 Store App with HTML5 and JavaScript. Finding a way to Inspect Element as if I was using Chrome or Safari wasn’t possiblee.

I knew Microsoft would have solved this issue and I couldn’t find anything using Google. That’s because I was googling ‘Windows 8 Store App page inspector’ whereas I should have been Googling ‘Windows 8 Store App DOM Explorer’.

Now that I have the correct search term; Quickstart: Debugging apps (JavaScript)

In short:

  1. Debug the Metro app in Simulator or Local Machine,
  2. Switch back to Visual Studio 2012,
  3. Press F12 or click DOM Explorer.

Speed up Visual Studio 2010 (RAMDisk)

 

Visual Studio can at times be painfully slow. From startup, to compile, to running the web-application. Without having to resort to hardware solutions which can cost $$$ I investigated how to get Visual Studio running as fast as possible. This included tweaking VS options and using a RAMDisk.

tl:dr Using a RAMDisk may halve compile times (your milage may vary)

Solution Compile Times
7200rpm HDD RAMDisk
23 seconds 12 seconds

Tweaking VS Options

First up I recommend reading this article from Daniel Fisher. This will give some great tweaks to VS options and anti-virus exclusions to give your system a small speed boost (note: I prefer to leave ‘Track active item in Solution Explorer’ on).

RAMDisk

Next up I tried setting up a RAMDisk to simulate having an SSD. A RAMDisk will take some of your system RAM and make it appear as a very fast drive on your system. The size of the RAMDisk will reduce the amount of free RAM. If you have 6GB RAM and the RAMDisk is 2GB, this will leave 4GB of available RAM for the OS and other processes.

To give you an idea of how fast your system RAM compared to a 7200RPM HDD I used a simple benchmarking tool (CrystalDiskMark).

HDD speeds in MB/s
7200rpm HDD RAMDisk
Read 105 4995
Write 85 3554

Setting up RAMDisk

Download RAMDisk, install it and create a RAMDisk size ~1024MB. Configure it so it should automatically Load/Save the RAMDisk image. And I recommend turning on the AutoSave for approx ~15 minutes (900 seconds).

After you create the RAMDisk open the Windows Disk Management app and partition/format the new drive (NTFS, quick format) to drive R:.

I tried two different approaches to using the RAMDisk so I’ve separated these into “Phases”. Phase 2 is slightly more complicated.

RAMDisk – Phase 1

With the RAMDisk running create a folder on the drive R:\”tempvs”.

r:
mkdir tempvs

Let’s now tell Visual Studio to use this RAMDisk for it’s temporary folder. Create a batch file vs2010.bat with the contents:

set TEMP=R:\tempvs
set TMP=R:\tempvs
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"

Also tweak your web.config so ASP.NET dynamic compilation system can run as fast as it possibly can with the tempDirectory attribute:

&lt;compilation debug="true" strict="true" explicit="true" tempDirectory="R:\tempaspnet"&gt;

If there was a speed boost at this point it was negligable.

RAMDisk – Phase 2

Now I wanted to see the compile time performance if I moved all the project source on to the RAMDisk too. By using a symlink from our current source location to our RAMDisk means there is no configuration changes or mucking around with the Solution or Project files.

If 1024MB RAMDisk isn’t big enough for your projects source code, resize it. (The existing RAMDisk will be lost and you have to create a new one).

Please backup your HDD or commit to source control before attempting this.

Copy solution folder on to the RAMDisk. Example c:\source\client\project => r:\source\client\project.

Rename (or remove) the existing solution folder. Example c:\source\client\project => c:\source\client\project_before_ramdisk

Now create the symlink to the solution folder on the RAMDisk (I’m using Windows 7, unsure if the command line differs for Vista)

c:
cd \source\client\
mklink /d "project" "r:\source\client\project"

You will now have a symlink from c:\source\client\project => r:\source\client\project. When you start Visual Studio and open your project from c:\source\client\project (like normal) the project should just load. With luck it will feel snappier and your compile times will be faster.

RAMDisk – Observations

Running a RAMDisk didn’t appear to have the speed benefits that I would have originally expected. I think because the .NET compiler has been optimised into oblivion the speed benefits of the RAMDisk is minimal.

That said, halving the time your waiting on the compiler is a big win.

Also if you’re running a SSD or RAID 0 solution on your PC already, I doubt there will be much benefit to you. Also if you’re already using fast disks you’re getting all-round speed benefits rather than just using a RAMDisk for source compilation.

So what speed difference did I observe?

Solution Compile Times
7200rpm HDD RAMDisk
23 seconds 12 seconds

Overall VS2010 feels snappier, and if you’re compiling many times a day and/or frequently running your Unit Tests the difference of even a few seconds will add up over days/weeks/months.

Turning off the RAMDisk and returning to my previous set up feels sluggish compared, so I will keep with this solution for the time being.

RAMDisk Warning

I want to be very clear that you’re using a RAMDisk. This means if your computer loses power you will lose your changes! That is until the RAMDisk is written to its image or you’ve committed to SCM you are running a risk.

Cheap Hardware Solutions

I also installed a 2nd HDD and moved the System Page file on to it as well as the SQL Server database MDF/LDF files.

I honestly can’t think of much more, I’m clutching at straws on this one.

Slightly more expensive Hardware Solutions

Upgrade to an SSD, 10,000RPM HDD or RAID 0 the HDDs. Not only will your compile times decrease, but you’re also going to see speed benefits for IIS, Visual Studio start up times, etc.

Get as much RAM as your boss will allow (whether that be management or wife).

Throw as much processing power as you can afford at the problem. I’m running an i7 2.8GHz and wishing for more.

Moving VS2010 on to RAMDisk

I created a 2GB RAMDisk and symlinked VS2010 onto it! I was hoping for a massive speed boost! Sadly this was not the case.

VS2010 Start Up Times
7200rpm HDD RAMDisk
1:15 0:43

As this computer has 6GB RAM, with a 2GB RAMDisk I’m now down to 4GB of available RAM. At this point I believe the amount of available RAM for VS is now to low and the system is starting to page. Perhaps if I had 8GB+ RAM this would be a viable solution.

System Specs

Intel Core i7 at 2.8GHz
6GB RAM
7200RPM HDD

Sources: lennybacon.com codewrecks.com

Determine if a String IsNumeric in C#

I’ve seen several implmentations of an IsNumeric() method in C# and all of them are woeful. Some examples involve casting and catch then catching exception, other (worse) examples recommend using Regular Expressions to check for only digits (no joke)!

Here’s a nice and simple Extension Method to determine if a string IsNumeric().

?View Code CSHARP
/// <summary>
/// Determines whether the specified string is numeric.
/// </summary>
public static bool IsNumeric(this string input)
{
	double value;
	return double.TryParse(input, out value);
}

I’ve even got some very simple Unit Tests to go with it (I understand I should not unit test .NET, but I wanted to ensure my implementation was fine).

?View Code CSHARP
[TestMethod]
public void IsNumeric_Numeric_String_Should_Evaluate_True()
{
	var expected = true;
	var text = "123456789.5";
 
	var actual = text.IsNumeric();
 
	Assert.AreEqual(expected, actual);
}
 
[TestMethod]
public void IsNumeric_Not_Numeric_String_Should_Evaluate_False()
{
	var expected = false;
	var text = "123456789rabbits";
 
	var actual = text.IsNumeric();
 
	Assert.AreEqual(expected, actual);
}

Updated (5-June-2011): This method only tested whole numbers, decimals are now supported.

Posted in C#

Permalink 1 Comment

How to use iOS Home Sharing

Without a doubt the new iOS Home Sharing feature introduced in iOS 4.3 is a big deal, in fact it’s a huge deal. Strangely, it’s not talked about anywhere near as much as Hotspot tethering. I guess you could call this the sleeper-hit of 4.3.

Ever since I purchased my first iOS device back in 2007 – 4 years ago – I’ve wanted a way to easily (read: built into the OS) stream music from my iMac. Then with later iOS devices – think iPad to stream movies – this desire only became stronger. This feature always seemed a natural fit for the iOS/iTunes ecosystem, surely with Bonjour it would be a piece of cake to implement, right?

Time passed and Apple released the Remote app; it didn’t allow you to stream content from iTunes, it simply allowed gave you the ability to tell an AppleTV to stream from iTunes. Boring.

3 years later here it is. iOS 4.3 give us Home Sharing and the ability to stream content from iTunes direct to your iPhone/iPod/iPad using Home Sharing. Sadly the feature has to be turned on from settings and is not automatically configured from iTunes 10.2 (but let’s talk enhancements later).

How to setup iOS Home Sharing

1. If you haven’t already you need to setup iTunes for Home Sharing; from the iTunes menu Advanced > Turn on Home Sharing.

2. On your iOS device. Settings > iPod > scroll to Home Sharing and type in your Home Sharing username/password you configured in step 1.
Turn on Home Sharing

3. Now open the iPod app. If you’re on an iPhone/iPod tap the More icon and then tap Shared.

iPhone/iPod access a Shared Library

If you’re using an iPad tap the Library header.

iPad access a Shared Library

(If your iTunes library is large it might take a while).

Enhancements and Issues

I’d like iTunes to automatically recognise that I’ve not configured Home Sharing on the device and it asks me if I would like to pre-populate the Home Sharing credentials. This would reduce the complexity of setting up Home Sharing, and would also be following that great Apple motto, “It just works”.

I’ve had some issues moving between my iTunes library and the on device library. After leaving a iTunes share the iPod app does not recognise my Podcast collection and I have to restart the iPod app on the iPhone.

Interestingly on the iPhone you cannot add the Shared item on to the TabBar for quick and easy access.

Posted in Apple, iOS

Permalink

IronRuby in Visual Studio – Console Tips

These are more a collection of IronRuby 1-liners for prosperity (ie my poor memory). I like to use IronRuby to be able to execute small snippets of code without having to run up a whole VS solution/project.

Using IronRuby Interactive in Visual Studio 2010

Install IronRuby from CodePlex, download from here.
After installation open Visual Studio and using the menu: View > Quick Access; in the search box type ‘Iron’.
Click IronRuby Interactive.

DateTime

System::DateTime.UtcNow.AddMinutes(-10)
System::DateTime.UtcNow.Subtract(System::TimeSpan.from_minutes(5))

Launch at Login Controller for your Mac Cocoa App

Ever needed your Cocoa/Objective-C application to Launch at Login? And also have your app appear in your users System Preferences > Accounts > Login Items list? Want this integration to be super-mega-piss-easy?

Well now you can.

We’re going to wrap LSSharedFileList to get our App to start at login – a Cocoa solution – as opposed to other solutions that use Carbon or having to edit XML system pref files.

Take a look at Github – Launch at Login for the source. Don’t forget to look at the readme for assistance for implementation.

Basically copy the LaunchAtLoginController.h/.m files into your project then either you can implement with Code or with Interface Builder.

Code

Will app launch at login?

LaunchAtLoginController *launchController = [[LaunchAtLoginController alloc] init];
BOOL launch = [launchController launchAtLogin];
[launchController release];

Set launch at login state.

LaunchAtLoginController *launchController = [[LaunchAtLoginController alloc] init];
[launchController setLaunchAtLogin:YES];
[launchController release];

IB

  • Open Interface Builder
  • Place a NSObject (the blue box) into the nib window
  • From the Inspector – Identity Tab (Cmd+6) set the Class to LaunchAtLoginController
  • Place a Checkbox on your Window/View
  • From the Inspector – Bindings Tab (Cmd+4) unroll the > Value item
  • Bind to Launch at Login Controller
  • Model Key Path: launchAtLogin

Easy right?

So what are you waiting for? Grab the code from Github – Launch at Login

Barebones CAEmitterLayer aka Particle Effects

CAEmitterLayer: use to create particle effects. Each particle is an instance of CAEmitterCell. (10.6) – cocoadevcentral

How could you not be intrigued? Particle Effects! Well I’ve always been interested in Particle Generators, and there’s one right here in Snow Leopard. How exciting. /claps.

I recently took a look at the Fire and Fireworks sample code that Apple and was duly impressed by what Core Animation provides for so little cost both code-wise and CPU resources. So I decided to write the simplest – barebones – CAEmitterLayer code where I was only dependant on the NSView it draws on.

There’s no fancy-pants stuff going on here, just a raw, simple, single particle effect. But it gives you a great perspective on how it works and the minimal code required to have a great particle animation.

Screenshot of this project

If you’re starting afresh you’re going to need to tell your project that we want to use Core Animation so:

  • Right click the Frameworks > Linked Frameworks on the left,
  • Add > Existing Frameworks…
  • Scroll to QuartzCore.framework > Add,
  • And make sure your ParticleController header file contains #import <QuartzCore/QuartzCore.h>.

Looking at CAEmitterLayer briefly (and ignoring setting up Interface Builder & the Nib) in our header file we simply need a CAEmitterLayer:

IBOutlet NSView *view;
CALayer *rootLayer;
CAEmitterLayer *emitter;

Where as the implementation file is going to need a whole lot of data for the Emitter plus we need to create a CAEmitterCell for the particle itself.

//Create the emitter layer
emitter = [CAEmitterLayer layer];
emitter.emitterPosition = CGPointMake(CGRectGetMidX(rootLayer.bounds), CGRectGetMidY(rootLayer.bounds));
emitter.emitterMode = kCAEmitterLayerOutline;
emitter.emitterShape = kCAEmitterLayerCircle;
emitter.renderMode = kCAEmitterLayerAdditive;
emitter.emitterSize = CGSizeMake(50 * multiplier, 0);
 
//Create the emitter cell
CAEmitterCell* particle = [CAEmitterCell emitterCell];
particle.emissionLongitude = M_PI;
particle.birthRate = multiplier * 1000.0;
particle.lifetime = multiplier;
particle.lifetimeRange = multiplier * 0.35;
particle.velocity = 180;
particle.velocityRange = 130;
particle.emissionRange = 1.1;
particle.scaleSpeed = 0.3;
CGColorRef color = CGColorCreateGenericRGB(0.3, 0.4, 0.9, 0.10);
particle.color = color;
CGColorRelease(color);
particle.contents = (id) [self CGImageNamed:@"spark.png"];

For the complete implementation file or the complete project please feel free to grab the source code from the bitbucket project.

iPad User-Agent String

At least just for my own notes here’s some iPad/iPhone user-agent string:

iPad 3.2 beta 2 (7B320c)

mozilla/5.0 (ipad; u; cpu os 3_2 like mac os x; en-us) applewebkit/531.21.10 (khtml, like gecko) version/4.0.4 mobile/7b320c safari/531.21.10

iPhone 3.1.3 (7E13) – Simulator

mozilla/5.0 (iphone simulator; u; cpu iphone os 3_1_3 like mac os x; en-us) applewebkit/528.18 (khtml, like gecko) version/4.0 mobile/7e18 safari/528.16