Twitter
Powered By
Powered by Squarespace
Navigation

Entries by James (38)

Tuesday
Oct162012

Using a script to set the Copy Local flag to false

As with my previous post I recently came across a repeatable task that we will probably want to repeat in the future so with my aim from The Pragmatic Programmer I decided to automate it.

The problem was that an architecual requirement of this project was to rely on DependencyInjection for all library references. To help enforce this every project outside of the DI one would require the Copy Local flag on all references set to false.

I started doing this manually but figured out it'd take a long time to go through all 40+ projects and this would happen in the future. So automation time it was.

A quick web search did not show that anyone had solved this problem before so I figured out I would have to learn some Powershell and make it myself.

As csproj files are simply XML I did some research to find out how easy it was to manipulate XML in Powershell. It turned out this is one of Powershell's strengths. However the first implementation had issues with namesapces so I had to use the Select-Xml command introduced in Powershell v2.

Building the XPath queries was fairly simple. The one hiccup to remember is that csproj xml has a default namespace of "http://schemas.microsoft.com/developer/msbuild/2003" so you need to remember to use that and the msb namespace prefix when making your XPath queries. To specify the namespace in Select-Xml you use the -namespace option.

Select-Xml -namespace @{msb = $projectNamespace} -xpath $privateXPath

The next step was saving out the changes. This proved to be an initial roadblock as all the files were set to readonly. As we are using TFS you have to explicitly checkout the files before you can edit them. This resulted in me looking into how to use the TFS command line executable "tf.exe". This proved to be fairly nice as I could simply pipe the collection of csproj files I wanted checked out to a chunk of script that would iterate through the collection and execute the checkout command on each file with the provided TFS credentials.

I explicitly did not attempt to check in the changes as I want the user to review the changes and make sure the solutions are still working. This is something you'd run once a month to make sure the requirement is still being followed.

The final hiccup was that the .NET XML classes Powershell uses has an issue with putting in a default empty namespace whenever you create a new element. This caused the project to fail to load in VisualStudio as the namespace was incorrect. The fix for this was pretty quick and easy. Take the file and replace any occurance of xmlns="" with an empty string. This is accomplished in Powershell with line

(Get-Content $projFilenameFull) | Foreach-Object {$_ -replace ' xmlns=""', ""} | Set-Content $projFilenameFull

So my first non-trivial powershell script was a fun and fiddly dive into scripting all my troubles away. So far so good. ;)

SetCopyLocalInAllCsProjFiles.ps1

Tuesday
Oct162012

Deleting all bin and obj folders from a solution

Quick little post.

Since reading The Pragmatic Programmer by Andrew Hunt and David Thomas I've been looking for ways to automate tasks whenever I find myself doing something I know I'm going to repeat later or I'm repeating right there and then.

The other day I was working on a VisualStudio Solution someone else had started and when trying to build it found they had checked in some of the bin and obj folders.

So I open up the root folder of the solution and prepare to trawl through about a dozen projects to delete all the bin and obj files. Obviously noticing that I'm about to do the same steps repeatedly and this will happen in the future I went and did a quick search to see if anyone else had already solved this.

Awesomely someone had.

So a huge thanks to Glenn at Development on a shoestring for providing exactly what I needed. I'm putting this here just in case his site should disappear and take the knowledge with it.

I threw the following into a powershell script that sits in source control ready for use in the future

# Iterate through all subdirectories and delete all bin and obj folders
# http://blog.slaven.net.au/2006/11/22/use-powershell-to-delete-all-bin-obj-folders/
# Had to use it for getting rid of a bunch of bin and obj folders in a PoC but thought it smart to put in here for other to use
Get-ChildItem .\ -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }
RemoveAllBinAndObjFolders.ps1
Friday
Jan202012

Connecting an iOS device to a mixed 802.11b/n WiFi network

In a recent visit to home I was presented with an old problem that had become a real annoyance. The iOS devices owned by the family (minus the iPad) including my iPhone would not connect to the house WiFi network. They would happily detect them but the moment they tried to connect they would time out.

It took a bit of pecking around and trial and error but I found a single change that then allowed all the devices to connect.

It boils down to only allowing 802.11b to operate on the 2.4GHz band instead of the default dual b/n. It see,ms the iPhone and iPod Touch devices do not play nicely with dual use of that band by the b and n standards.

Monday
Jan172011

Event Handlers only firing once in Microsoft Office AddIns

I've just been working on a project where we were to create some AddIns for several versions of Microsoft Office. Now I knew there was a lot of bad blood around Office AddIns but thought they were being overblown as I finished off the 2010 AddIn without so much as a hiccup. The 2007 and 2003 AddIns however showed why Office has the reputation it has.

The problem I ran into was that I had to have several event handlers to catch two events. The opening of a new inspector and a simple button click. So I did what you'd expect to do and registered them in the startup methods.

Initial testing went fine as I started up Outlook and triggered one event, made some changes, restarted it and then tested the other event. It took a while until I tried to test both events following one another at which point I found only one would trigger and then both would even handler hooks would be forgotten and wouldn't rehook in until a restart of the application.

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Outlook.Explorer explorer = this.Application.ActiveExplorer();
        Outlook.Application app = (Outlook.Application)explorer.Application;

        app.NewInspector += new InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
    }
}

After much searching I began to come across implications that the garbage collector was removing the references after the first event. I was at a loss at what to do until I came across another discussion where someone was having a similar problem and the response was to save the object in a class level variable to avoid the garbage collector from removing it.

A quick edit and some testing showed this to work reliably. So, if Office is only triggering an event once make sure there object references are stored somewhere the garbage collector won't go. And make sure to assign the object before you register the handler or the garbage collector will still find it.


public partial class ThisAddIn
{
    public Inspectors _appInspectors;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Outlook.Explorer explorer = this.Application.ActiveExplorer();
        Outlook.Application app = (Outlook.Application)explorer.Application;

        _appInspectors = app.Inspectors;
        _appInspectors.NewInspector += new InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
    }
}

Wednesday
Aug112010

Starcraft II Patch Download Problem

Since getting Starcraft II I have bashed my head against the uselessness of the Blizzard Downloader. As is common knowledge that Blizzard uses the bittorrent protocol to transfer its patches and you might thin that it's pretty damn penny pinching of them to do it instead of just doing direct downloads. Unfortunately their bittorrent sucks from my repeated experience.

On both the 1.0.1 and 1.0.2 patches the downloader stopped part way through the download reporting the error "There were multiple problems saving data." As you can tell it offered up no useful help. A quick Google also turned up very little other than the basic and generic Blizzard Downloader FAQ page. After trying all of the suggestions I had got nowhere except swearing at Blizzard for not putting out a direct download patch.

To keep this short a few days later I tried downloading the patch files into the Updates folder using utorrent instead of the Blizzard downloader and five minutes later all the files had been downloaded. The Updates folder is located in the Starcraft II install folder and is only there when there's a patch needing to be downloaded. Starting up Starcraft II again it detected all the files were present and happily patched itself up.

So if you're having trouble downloading the Starcraft II patches wait a couple of days and try using a different bittorrent client to download the files. You'll find the bittorrent files near the Updates folder in the Starcraft II install folder.