There’s a lot of UI research going on focused around better debugging. Debugger Canvas is some that you can use today and the version 1.1 was just released. The speed increased in 1.1 are great and make Debugger Canvas much more usable. I’m in love with the toggle button where you can flip between Debugger Canvas and regular text file display. While I have a few feature requests that I’d love to see, using 1.1 made me wish for some more. My feedback’s been given to the Debugger Canvas team but I thought it might spark some discussion by mentioning my additional wishes to everyone:

  • When using Debugger Canvas on a multithreaded application, I’d love to see the thread ID and/or name in the display when it’s an active call stack. It’s a little to easy to get lost in a multithreaded canvas.
  • It would be nice to have a timestamp on a bubble. When one canvas is getting reused you can see at a glance which is the most recent chain.
  • It would be nice to have a way to remove a whole chain at once.

Please do let the team know your feedback at the DevLabs Debugger Canvas forum.

Business is good and we need YOU! Wintellect is currently seeking senior level technical development resources for both contract and permanent employment for our current client projects. If you want the challenge of keeping up with co-workers like Jeffrey Richter, Jeff Prosise, Keith Rome, or Jeremy Likness, have we got the opportunity of a lifetime. Please have lots of hands on development experience in the following technologies: C#, ASP.NET MVC, WPF, WCF, Silverlight and SQL Server. Experience with HTML5 and jQuery would be ideal also. If you can't tell, it's all cutting edge here at Wintellect so if you like doing the latest technology we'd love to talk with you. Please forward your resume and availability to Barbara Keihm, Director of Human Resources, bkeihm@wintellect.com.

Paraffin 3.6 can be downloaded here: http://www.wintellect.com/CS/files/folders/18310/download.aspx

Dan Gough had an excellent feature request to have Paraffin copy over any manually added namespaces to the .WXS file like the following. Previously, Paraffin ignored them, but no more.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Wix xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
  3.      xmlns="http://schemas.microsoft.com/wix/2006/wi">

I updated Paraffin to copy over any namespaces added to the Wix element when creating the .PARAFFIN file. If you were having Paraffin inject additional elements with a .ParaffinMold file, now it’s easier than ever to keep your WiX fragments up to date.

When adding custom namespaces, put them before the default xmlns="http://schemas.microsoft.com/wix/2006/wi" as I’ve shown in the snippet above. With LINQ to XML, the xmlns attribute is special and does not show up in the Attributes collection so there’s no way I can sort it with the rest of the values. When generating the output XML file, XDocument always puts the xmlns attribute last. I tried all sorts of tricks to get it placed first but never got them to work.

There’s no trouble if you place your custom namespaces after the default xmlns, but in the .PARAFFIN file they will always appear first so you’ll see more changes when you diff the .WXS and .PARAFFIN file.

Please do let me know if you have feature requests! I considered adding a command line switch to allow adding custom namespaces when creating a .WXS fragment but didn’t think that would be used very much so decided against it. Of course, now that I’ve mentioned this option everyone’s going to ask for it. <grin!>

If you’re not familiar with Paraffin, please read the Zen of Paraffin document in the root directory of the download.

The other day I was asked which extensions for Visual Studio I use so in an effort to save keystrokes, I thought I’d list them here so I can refer people to this list. There’s no way this is a comprehensive list and I do add and remove extensions all the time. However, these are the ones that always stay installed because if they aren’t, I can’t use Visual Studio. By the way, these are all free.

Productivity Power Tools

Want a bunch of features for the next version of Visual Studio today? That’s exactly what Microsoft’s Productivity Power Tools are all about. Once you use the awesome Solution Navigator, you’ll wonder how you ever lived without it. Add in the better Tab Well UI, Quick Find, and all the other enhancements and you’re in Visual Studio heaven. This is the single most important extension available.

NuGet Package Manager

The first time you add an open source package to your solution, you’ll thank your lucky stars for this extension. It’s quick and easy so you can focus on what you need to do instead of the integration. What I find even better than the package manager is that NuGet adds a PowerShell window to Visual Studio. I’m using that constantly these days because the $dte variable exposes the Visual Studio automation model to PowerShell.

VS Color Output

This fine extension adds color-coding to output windows in Visual Studio. Seeing build breaks in red and good builds in green, as well as control over all other output, is something that should have been built into Visual Studio already. The latest version 1.1 update fixes a crashing issue people were reporting.

HTML Spell Checker

I can’t spell at all and this extension keeps me from looking like moron as others look at the comments in my code.

Highlight All Occurrences of a Selected Word

A super simple extension that does exactly what the title says. It’s wonderful when doing presentations to highlight a word and for looking at all uses of a global variable. Note that this extension offers no customizability so you’re stuck with the lime green highlight that does not work so well with you wild kids using dark background themes.

So what extensions can you not live without? I’d love to know what extensions you use so either blog about them or add them to the comments.

Edit: Make sure to read the comments from Shay Levy and Richard on clarifying my mistaken assumptions about how things work in PowerShell. Thanks to Richard & Shay for the clarifications! 

As I’m a command line kind of guy, I look for every opportunity to stay in a PowerShell window at all times. “Why grab the mouse when you don’t have?” to is my motto! The other day I was working on my laptop and was running short of battery power so wanted to switch to the Power Saver plan. A quick search told me POWERCFG.EXE was the command line tool to use.

Hold on there Flash! POWERCFG.EXE with the –S option is the command line way to change power plans, but to specify the plan you must use the GUID of the plan. While I’m a big fan of GUIDs there’s several places where GUIDs are not appropriate: command line tools, URLs, and any other place where end users could see them. Shouldn’t you just be able to set the power plan by name like “Balanced, ” “Power Saver,” or if you are feeling randy, “High Performance?” That’s an oversight that needs to be fixed so below is a PowerShell script, Set-PowerPlan.ps1, that lets you set the power plan at the command line based on the name of the plan instead of an ugly GUID.

The basic idea of the script is to get the list of defined power plans from “POWERCFG.EXE –l” and parse the output with a regular expression looking for the plan name with matching GUID. With the GUID in hand calling “POWERCFG –s <GUID>” flips to the defined plan. The regular expression work was simple, but there was one thing that stumped me.

In all the PowerShell work I’ve done I’ve never needed to capture the output of an old-school command line program like POWERCFG.EXE. It seemed so simple to do something like “$plans = POWERCFG –l” to get the list of plans and parse the output with “$plans –match <some regex>” to pull out the GUID. Little did I know that would definitely not be anything approaching normal. Yet again a PowerShell-ism reached up and dope slap me hard.

Interactively in a PowerShell console window, I ran “$plans = POWERCFG –l” and double-checked that $plans was a string by executing “$plans | Get-Member” as piping to Get-Member will report the type of object. Sure enough I was looking at a System.String. Oddly, when I ran “$plans –match <regex>” it always returned false even though typing “$plans” definitely showed me the complete output of the “POWERCFG –l” and the exact string I was looking for was there.

What totally confused me was running “$plans.Length” as that reported “7” instead of the 364 characters I counted in the string. After a bunch of reading I finally realized that $plans is really a freaking ARRAY of seven lines instead of a complete string. When PowerShell captures the output of a regular command line program as an array of strings. Whenever one is first exposed to PowerShell you invariably are taught about the Get-Member command right at the beginning to figure out the type of an object. When Get-Member lies to you it’s hard to get a clue. It’s things like this that make you understand why so few developers have switched over to PowerShell.

If you want all the output of a regular command line program into an actual string you have two choices. The first is to explicitly type the receiving variable with [string] like the following: “[string]$plans = powercfg -l” The alternative is to gather the regular command output into a variable, but if you need to look across all that output pipe the variable array to Out-String surrounded by parenthesis as in “($plans | Out-String)”.

I’m sure some PowerShell Ninja will jump in here and tell me how I missed the obvious, but I don’t feel I did. Hopefully, this little PowerShell gotcha will help you go down the PowerShell route with more confidence. While PowerShell has some bumps along the way the journey is totally worth it!

Set-PowerPlan.PS1
  1. #requires -version 2.0
  2.  
  3. # (c) 2012 by John Robbins\Wintellect
  4.  
  5. <#.SYNOPSIS
  6. Sets the current power plan.
  7. .DESCRIPTION
  8. The POWERCFG.EXE utility requires GUIDS when changing a power plan instead of
  9. the name of the plan. That's highly inconvenient so this simple script allows
  10. you to use common sense names like "Balanced" or "Power Saver" instead.
  11.  
  12. To get the list of power plans on your computer execute 'powercfg -l'
  13. .PARAMETER Plan
  14. The name of the power plan to use.
  15. .EXAMPLE
  16. Set-PowerPlan -Plan Balanced
  17. Sets the power plan to the Balanced plan, the recommnded Microsoft plan.
  18. .EXAMPLE
  19. Set-PowerPlan "Power Saver"
  20. Sets the power plan to the Power Saver plan to reduce battery usage.
  21. .LINK
  22. http://www.wintellect.com/CS/blogs/jrobbins/archive/tags/PowerShell/default.aspx
  23. #>
  24.  
  25. param ($Plan = $(throw 'You must specify the power plan, use "powercfg -l" for the plan names' ))
  26.  
  27. Set-StrictMode -Version Latest
  28.  
  29. # Get the list of plans on the current machine.
  30. $planList = powercfg.exe -l
  31.  
  32. # The regular expression to pull out the GUID for the specified plan.
  33. $planRegEx = "(?<PlanGUID>[A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}\-){3}[A-Fa-f0-9]{12})" + ("(?:\s+\({0}\))" -f $Plan)
  34.  
  35. # If the plan appears in the list...
  36. if ( ($planList | Out-String) -match $planRegEx )
  37. {
  38.     # Pull out the matching GUID and capture both stdout and stderr.
  39.     $result = powercfg -s $matches["PlanGUID"] 2>&1
  40.     
  41.     # If there were any problems, show the error.
  42.     if ( $LASTEXITCODE -ne 0)
  43.     {
  44.         $result
  45.     }
  46. }
  47. else
  48. {
  49.     Write-Error ("The requested power scheme '{0}' does not exist on this machine" -f $Plan)
  50. }

So you have an awesome minidump your IT guys grabbed with ProcDump. You’ve followed all the rules and have a Symbol Server and Source Server all set up. You open that dump with Visual Studio and BOOM, none of your indexed sources show up. You pull your hair out trying to get your public build sources appear but they never do and it’s just “SRCSRV: The module ‘<<path to the exe file>>’ does not contain source server information.” for everything in the Output window.

Fortunately, a smiling bald guy, Andy Hopper, figured out how to make it all work. Turns out when opening a minidump, the “managed debugging engine tries to verify that each source server enabled assembly is running as a fully trusted assembly from the CLR’s perspective.” Ahh, nothing like security to turn off a feature. The great news is that you can tell the managed debugging engine to stop doing the checks so the Source Server works with the managed minidumps. It’s as simple as setting a registry key. Swipe the registry script below and you are good to go.

All credit to Andy Hopper on this one!

  1. Windows Registry Editor Version 5.00
  2.  
  3. ; Enables Source Server support when opening up managed minidumps in Visual Studio.
  4. ; All credit to Andy Hopper!
  5. ; http://smilingbaldguy.wordpress.com/2012/01/06/managed-minidump-debugging-now-with-source-server-support/
  6. ; If you're on a 32-bit machine (and why would you be?) remove Wow6432Node.
  7. ;
  8.  
  9. [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\AD7Metrics\Engine\{00000000-0000-0000-0000-000000000000}]
  10. "RequireFullTrustForSourceServer"=dword:00000000

In the development world, there’s a lot of things that bump, distract, and annoy you through the day. Those get a lot of attention in blogs to help others work around those issues and to document the pain. What does not get a lot of attention are those things that work well and make your life better. In this blog post I want to shout the kudos for a few things I’ve been enjoying immensely in the last month. My list will not be anything as good as Scott Hanselman's 2011 Ultimate Developer and Power Users Tool List for Windows, but I’m sure loving what I mention below!

1Password from Agile Bits

With the news the last few years talking about security breaches and research showing everyone is using the same password everywhere if you’re not using a password manager you are plain crazy. I’ve been using 1Password for a while now and it’s so well integrated in all browsers across Windows, OS X, and phones, I basically forgot I was using it. When setting up a new machine recently I was perplexed for a minute as to why I couldn’t log into various web sites and where was the password button in the web browser? 1Password does its job so well I can’t help but recommend it because I forget I’m running it.

Speaking of passwords and security, all developers need to read the wonderful research paper “So Long, And No Thanks for the Externalities: The Rational Rejection of Security Advice by Users” by Cormac Herley of Microsoft Research. It discusses why normal people always use the same password and weak ones at that.

SlySoft Virtual Clone Drive

Windows 8 will finally have native ISO mounting support built in to the OS. It’s about time. However, with Windows 8 not releasing for quite a while you need something today to mount those ISO files. Virtual Clone Drive has been around for years and works on all Windows OS. I don’t have any software on a DVD any more because either downloaded it or converted it to ISO files. When using Virtual Clone Drive, select the Virtual Sheep option so your fake DVD drive shows up with the awesome angry sheep icon. The price is awesome for Virtual Clone Drive: free.

Other World Computing Data Doubler

As it was time for a laptop upgrade, I kept with my love of Apple hardware and bought a 15-inch MacBook Pro. As I’ve said many times to people: “Apple: The best Windows machines money can buy!”™® Because I don’t use DVDs any more the Apple drive is just taking up space in the machine. Fortunately, the fine folks at Other World Computing (OWC) have a great solution in Data Doubler that replaces your DVD with another hard disk. For $65 USD I slapped in the SSD I took out of my no longer needed desktop machine and instantly had another 240GB of sweet SSD speedy sexiness for my virtual machines.

The prospect of cracking open a unibody MacBook sounded daunting and I thought I might kill the magic hipster fairies that live inside of all Apple products. The good news is that OWC include all the tools you need to do the conversion and have fantastically detailed videos on all the exact steps for your particular machine. What I especially liked is that the Data Doubler came with replacement Phillips head screws to replace the hard to work with Torx head screws Apple uses in manufacturing. Now if I want to throw in a much bigger disk in the future, it will be that much easier to do it. That’s attention to detail!

VSColorOutput Extension by Blue Onion Software

Wading through the build output with a large project in Visual Studio is tedious. If only there were a way to use colors to have good lines in green, errors in red, and everything else in a gray it would be much easier to see what’s going on. Fortunately, Mike Ward over at Blue Onion Software did exactly that with VSColorOutput extension and it’s on my can’t live without list. Even better is that the code is open source on CodePlex so if you have never written a Visual Studio extension, it’s a great example.

Since I’m talking about Blue Onion, make sure to subscribe to Mike’s blog. His Friday Links posts always have something in them that I didn’t know about or find really interesting. My personal favorite category is the “Stuff I Just Like” links.

Microsoft IT VPN

It’s no surprise to you but there are a lot of problems with most VPN software. We have to use many different VPN solutions with all our clients and most of them range from painful to an all out death assault on your machine. You know, small issues like you can either VPN or hit the whole Internet but not both, each requires different anti virus software some of which are not up to date, and so on. Sadly, unless you are a Microsoft Employee or approved vendor you won’t get to see VPN software done outstandingly well. Microsoft IT has this awesome solution that uses smart cards in your badges before you connect, decent connection speed, killer security when you are connected, and never interferes with anything on your machine.

I really wish Microsoft would do some white papers on their IT VPN setup because it so much better than any other I’ve seen. Hopefully mentioning the internal VPN solution has won’t kill my NDA with Microsoft. I’m sure like any internal IT group, Microsoft IT only gets noticed when something isn’t working, but I just love their VPN solution and wanted to give them a solid shout out.

TFS Preview from Microsoft

Since TFS 2005 I’ve been running my own domain so I can use TFS and get experience with all of its facets. It was all a bit of overkill, because all I really need for my personal work is TFS Basics, but that wasn’t offered back in the day. TFS is an amazing product and it offers many bells and whistles that provide all the reporting and legal requirements that up to the largest organization requires. However, one thing I’ve noticed is that many teams use the same parts of TFS such as product backlog, bug tracking, version control, and build management, but never touch other pieces such as the SharePoint integration.

The TFS team has certainly noticed the same phenomenon and also saw an opportunity to provide hosted TFS. While TFS Preview isn’t formally in a beta with Dev 11 yet, I feel it’s the true killer release of TFS. For many teams it will hit the 90% sweet spot of their TFS usage, most likely provide a Service Level Agreement for uptime better than many internal IT organizations can offer, and be cheaper in the long run.

This last month I set up a full project with one-week sprints to work through using TFS Preview using the Scrum 2.0 template and I’m far more than impressed, I want to start throwing gobs of money at Microsoft right now! I couldn’t believe how polished the whole web experience has become and the Scrum board is my favorite Web 2.0 page ever. Other than companies with specific legal requirements for running your own TFS server, I can’t see why anyone would ever need to run their own TFS server. I wonder if there’s a business opportunity to offer automated migration of work items and check ins between your old server and the spiffy TFS Preview?

Parallels Desktop for Mac from Parallels

After Apple introduced Boot Camp that lets you boot the Macs into Windows, I was in all sorts of love because it is great hardware combined with zero crapware on Windows. I was more than happy to reboot between OS X and Windows whenever I needed to use one or the other. When Parallels first announced support for utilizing your Boot Camp a while ago (version 2.5), I gave it a try but quickly gave up because Windows and Office activations triggered whenever I switched between Boot Camp and Parallels. While I could have created a separate dedicated virtual machine, I didn’t want to waste the disk space for a second copy of Windows nor go through the installation hell of setting up a development machine twice and then trying to keep everything in sync between them.

When I bought my new Mac Book Pro, I figured I’d give Parallels another shot because being able to utilize Windows no matter if I was running OS X or Boot Camp seems very enticing. With version 7 the Parallels team completely and totally nailed it! I installed Windows in Boot Camp and activated it. Switching back to OS X, I installed Parallels, fired up the Boot Camp partition in a VM activated Windows again and that was it. I can use Windows (and Microsoft Office) either way and everything just works perfectly.

Parallels made it very easy to use the Windows VM full screen so that’s how I rolled for my initial usage. I’d read about the Coherence mode that allows all Windows applications to appear like normal OS X windows, but didn’t think it would be very useful. Let’s just say I was incredibly wrong. I love how smooth and seamless having all your windows from both operating systems running side by side. My wife came into my office and looking at the monitor could not figure out which OS I was running which I thought was pretty funny.

I just had a brilliant thought! With Windows 8 supporting Hyper-V on the desktop, if Microsoft would support your Apple OS X partition in Hyper-V you’d have the best of all possible worlds! Microsoft could call the feature Camp Boot just to make it even cooler. Being able to run OS X applications when you need them from Windows 8… Oh, please don’t make me wake up from this dream. <Grin!/>

Holiday Leftover Turkey Sandwiches

My wife is an amazing cook. If you ever meet me in person you will be able to tell that from my girth. Over the holidays she wanted to make a roast turkey so I certainly did not stand in the way because I love the big bird. While the turkey dinner is great, the leftovers are even better. Here’s the ultimate recipe for the food of the gods.

  1. Two slices of very fresh squishy white bread
  2. Spread Hellman’s mayonnaise on both internal sides of the bread (this is the secret!)
  3. Fill the bottom bread with a layer of turkey about a quarter inch thick
  4. Take a salt grinder filled with sea salt and lightly salt the layer of turkey
  5. Place a single layer of freshly chilled lettuce on the turkey before putting the top slice of bread on the sandwich
  6. Carefully mash the sandwich down until the bread conforms around the turkey
  7. DO NOT CUT THE SANDWICH IN HALF
  8. Pick up with both hands and enjoy!

So what have you find readers been enjoying over the last month?

Sometimes it’s easy to see why your .NET server application is using so much memory, but other times it makes no sense at all. I was at Microsoft earlier this week and someone who’d taken my debugging class stopped me and asked an excellent question. The scenario they had was their service memory would just grow at a steady rate without ever going down. The team found a fix for the memory leak through savvy internet searching but found it frustrating they could not see the answer through SOS and SOSEX. The person gave me the dumps as they wanted to know how they could have found the issue quicker. The research was pretty interesting so I thought I’d share the results.

The first command you always run after loading SOS is !dumpheap –stat so you can get a picture of the overall memory usage. On the dumps the team gave me, the result showed something very similar to the following at the end of the output:

  1. 0000000000386ce0        9         7328      Free
  2. 000007fee1d26ac8      464        18720 System.String
  3. 000007fee1d2afd0       34       183560 System.Object[]
  4. 000007fee1d478a0    11098       355136 System.WeakReference

In the real mini dump those WeakReferences were taking up over 270MB! The weak can kill you in the .NET world.

Whenever I see a WeakReference, you’re looking at some form of cache because it’s a special class that you use to reference an object, but allow that object to be garbage collected. So we know someone’s caching something, but who is doing the caching?

Running !dumpheap –type System.Weak yields the following output:

  1. 0000000002603f88 000007fee1d478a0       32     
  2. 0000000002603fa8 000007fee1d478a0       32     
  3. 0000000002603fc8 000007fee1d478a0       32     
  4. total 0 objects
  5. Statistics:
  6.               MT    Count    TotalSize Class Name
  7. 000007fee1d4f320        1           40 System.Collections.Generic.List`1
  8.                                        [[System.WeakReference, mscorlib]]
  9. 000007fee1d478a0    11098       355136 System.WeakReference
  10. Total 11099 objects

Yep, that List<WeakReference>, is probably the issue. So it’s time to look who created it by doing a !gcroot on it’s address.

  1. 0:004> !gcroot 00000000025ad460
  2. Note: Roots found on stacks may be false positives. Run "!help gcroot" for
  3. more info.
  4. Scan Thread 0 OSTHread b3c
  5. Scan Thread 2 OSTHread 3dc
  6. DOMAIN(0000000000399A60):HANDLE(Pinned):4c17d8:Root:  00000000125a7048(System.Object[])->
  7.   00000000025ad460(System.Collections.Generic.List`1[[System.WeakReference, mscorlib]])

Life just got miserable. .NET stores static fields in an Object Array for each app domain. The static array is pinned in memory so that’s the clue. Sadly, with .NET 4 SOS the only way to see which object has the List<WeakReference> as a field without manually dumping each object in the heap. Back in the .NET 1.1 days there was a way to pretty easily figure out the holding class, but Microsoft changed the implementation so it no longer works.

Fortunately, there is a way to figure out those static fields. All it takes is a little investment in the Professional edition on the amazing .NET Memory Profiler. Always purchase the Professional edition because that’s the version with the advanced feature to open mini dumps. Opening large mini dumps can take a long time as .NET Memory Profiler has to build up the reference chains and other data. However, I’m more than happy to let .NET Memory Profiler take it’s time because to do all of that work manually in SOS would consume months and make me give up technology.

After opening the mini dump of my sample program, which took about 60 seconds, I typed List into the Overview tab to narrow down to the List<WeakReference>

image

Double clicking on the on List<WeakRefefence> takes you to the Type details tab and shows you exactly who owns that pesky static.

image

It’s a TraceSource so we have the culprit! In fact, looking at the type instance graph shows the whole reference chain.

image

Looking at the TraceSource constructor in Reflector shows exactly where the WeakReference is created.

  1. public TraceSource(string name, SourceLevels defaultLevel)
  2. {
  3.     if (name == null)
  4.     {
  5.         throw new ArgumentNullException("name");
  6.     }
  7.     if (name.Length == 0)
  8.     {
  9.         throw new ArgumentException("name");
  10.     }
  11.     this.sourceName = name;
  12.     this.switchLevel = defaultLevel;
  13.     lock (tracesources)
  14.     {
  15.         _pruneCachedTraceSources();
  16.         tracesources.Add(new WeakReference(this));
  17.     }
  18. }

The _pruneCachedTraceSources method is interesting and shows exactly why those WeakReferences are all stuck in Gen 2.

  1. private static void _pruneCachedTraceSources()
  2. {
  3.     lock (tracesources)
  4.     {
  5.         if (s_LastCollectionCount != GC.CollectionCount(2))
  6.         {
  7.             List<WeakReference> collection = new List<WeakReference>(tracesources.Count);
  8.             for (int i = 0; i < tracesources.Count; i++)
  9.             {
  10.                 if (((TraceSource)tracesources[i].Target) != null)
  11.                 {
  12.                     collection.Add(tracesources[i]);
  13.                 }
  14.             }
  15.             if (collection.Count < tracesources.Count)
  16.             {
  17.                 tracesources.Clear();
  18.                 tracesources.AddRange(collection);
  19.                 tracesources.TrimExcess();
  20.             }
  21.             s_LastCollectionCount = GC.CollectionCount(2);
  22.         }
  23.     }
  24. }

Basically, the cache is only cleared whenever new TraceSource is added or a call to Trace.Refresh is made. In the Microsoft code they were mistakenly allocating a new TraceSource and TraceSwitch, which also has the WeakReference list, every time a connection came in. How this happened is that they converted what was a singleton static object into something they allocated on each call. That meant lots of TraceSource and TraceSwitch allocations but with this magic underneath causing big memory usage. You’ve probably guessed by now that you should always make your TraceSource and TraceSwitch fields statics so you hold only the one instance and avoid this potential memory issue.

Note that I’m not saying the implementation of TraceSource or TraceSwitch is wrong as it gives you the ability to refresh all your tracing in one call instead of making you manage all the individual instances yourself. That’s a nice feature of the tracing system in .NET. The implementation just doesn’t expect that you’ll be allocating hundreds of thousands.

While I would love SOS to have a better way to track down these static field problems, at least we do have a solution with .NET Memory Profiler.

So I have been installing new builds of Windows since NT 3.1 Beta 1 so I can’t help myself! After downloading Windows 8 Developer Preview I  of course had to give it a go on my ASUS EP121. It’s a full touch and pen slate computer that is one of the test devices in the Windows 8 labs. If it wasn’t for the Windows team admitting they were using my exact machine I would have probably been going the Hyper-V route. However, my horoscope said it was a good day so I figured what the heck, let’s go for the full install on real hardware. Below are the notes and raw feedback I took while doing the clean install. Take them as you will.

After creating a bootable USB from the Windows 8 Developer Preview ISO, I plugged my USB drive in and said “I’m feeling lucky.” After restarting the computer, the machine booted off the USB and the install started. I LOVED how the install recognized the touch and pen digitizers on the ASUS. Other than the power cord the only thing I had plugged into the system was the USB boot drive. It was pretty cool to walk through the install with my tablet pen in hand. When installing Windows 7 on this same machine I had to have a USB hub plugged in to get my mouse, keyboard, and bootable Win7 USB drive working.

As per the documentation, I chose a clean install and let the installer do it’s magic. Everything worked great and I have to give major kudos to the Microsoft lawyers for letting the first sentence in the EULA say

Make the lawyers happy by reading this carefully. (There won't be a quiz later)

The new setup experience went smooth and I loved how I could use the pen or on screen keyboard for entering the machine account as well as setting up the wireless network. All the devices on the machine were recognized and there was no need to download any drivers.

Just to make my life fun, I decided to join the machine to my domain after getting the initial OS installed. The process was exactly the same as it’s been in Vista and Windows 7. The only difference is that in Windows 8, you have to click the Control Panel tile, More Settings button, in the Metro UI as it’s not available from the Start menu any more.

As I still did not have a keyboard or mouse connected to the ASUS EP121, I was able to do all the operations with either the on screen keyboard or the pen. In both cases I’ve found them to be far better than I expected. When connecting to shares or entering product keys for Office the pen and onscreen keyboard worked great.

My first order of business after getting the OS installed was to get my slate computer usable in my business setting. At Wintellect we use Microsoft Office Online (what is now Office 365, but we haven’t been upgraded yet). That means the first application you install is the Sign On application. What I found neat was that the Sign In application needed .NET 3.5 so that triggered Windows 8 to add a .NET 3.5 as a feature and automatically apply all updates to it. Once that was complete, I could installed the Sign In application and life was good.

As Visual Studio 11 is already on the machine, the only other set of applications I need is the ubiquitous Microsoft Office 2010 so I can get email, write documents, and have access to my beloved OneNote. That install went smooth and life is good.

Disclaimer: The following is based off 120 minutes of using the computer. My opinion will probably change as I get more experience with the new UI.

Once I got the machine setup and working I was looking forward to digging in and seeing the new Metro UI. However, I found no matter how I tried, I have to be missing something because the Metro apps and approach don’t seem to be making me more productive or the computer more useful. I can totally see how the Metro UI would be wonderful and useful on an ARM tablet machine that you’re sitting on the couch using the computer to browse the web. It’s wonderful for that. However, for a desktop/development computer, all I do in Metro is poke at the Desktop or Control Panel links to get at real applications or configure the computer so Metro kind of gets in the way.

While they showed off a Metro mail client in the keynote, I can’t see how I would use something that limited to get real work done when I need to sit down and write a long email to a client with lots of details and screen shots. I realize this is a Developer Preview Release and I’ve been using Windows since version 2 so I may be set in my ways. I would love to be proven wrong but on first glance I’m having a hard time seeing how a tablet-like metaphor, that works fantastic for tablet mind you, extends to the desktop.

After a couple of hours using the computer, I found myself moving all my productivity application to the first “tile space” in Metro so I could get to them quickly after hitting the Windows key. While I love checking my stocks as much as the next investor, it’s not something I want to be doing every time I hit the Windows key. The same goes for the weather. I’m really struggling to try and like the Metro approach but something seems off to me. I feel the OS should better conform to the usage patterns of the device, or even ask the user when the first log in. If Windows 8 is installing on a SOC computer, the default should be light apps with web browsing and simple games as the default. It installing on a desktop/laptop machine it should conform to general productivity applications over the fluffier stuff.

These are just my initial thoughts from my initial usage. Granted, I have no idea what cool Metro apps we might be getting in the future. These thoughts are my raw thoughts dumped into this blog. Judge Metro on your scale. 

Please chime in with your thoughts on Windows 8 in the comments or your own blog and feel free to tell me how wrong I am about Metro.

On a mailing list I’m on Ed Blankenship pointed out that VS updates are now coming through Windows Update. Finally! Hopefully Microsoft will keep pushing these updates for all products they ship because it’s something of a pain to keep a development box up to date.

image

The other day I wrote about how to incorporate build numbers into your .CSPROJ and .VCXPROJ files. In doing some more testing I found in some edge cases where the way I was getting the current build number by including Microsoft.TeamFoundation.Build.targets could interfere with the TFS Build. That’s not good so I fixed the problem by declaring and using the GetBuildProperties task by itself. That avoids the odd build case and makes everything work. I’ve updated the sample with the latest Wintellect.TFSBuildNumber.targets file so grab it here.

In my previous post I showed the simple example of changing the one .CSPROJ or .VCXPROJ file that’s built at the beginning of your build. I was working on a large system that was broken into multiple .SLN files that could be built in any order. That meant I had to edit multiple projects and wanted to show how I simplified the integration into many projects.

First I created a common ,Targets file I called VersionNumbers.Targets that included everything necessary for creating the version number files for both C# and C++ projects. The comments in the file explain what’s going on. You can use this file as the basis of all your version number files.

Version Numbers.Targets
  1. <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  2.  
  3.   <PropertyGroup>
  4.     <!-- The following two properties are mandatory with
  5.          Wintellect.TFSBuildNumber.targets-->
  6.     <TFSMajorBuildNumber>5</TFSMajorBuildNumber>
  7.     <TFSMinorBuildNumber>0</TFSMinorBuildNumber>
  8.   </PropertyGroup>
  9.  
  10.   <!-- Assume the shared directory but allow it to be changed before
  11.        before including this file. -->
  12.   <PropertyGroup Condition=" '$(SharedVersionOutputDirectory)' == '' ">
  13.     <SharedVersionOutputDirectory>..\Shared</SharedVersionOutputDirectory>
  14.   </PropertyGroup>
  15.  
  16.   <!-- Include the targets that create the version number files. -->
  17.   <Import Project="Wintellect.TFSBuildNumber.targets" />
  18.  
  19.   <!-- C# and VB projects are easy, I'll just jam in the file creation on the included
  20.       BeforeBuild which will get everything hooked up perfectly. -->
  21.   <Target Name="BeforeBuild"
  22.         DependsOnTargets="WriteSharedTextAssemblyVersionFile;
  23.                           WriteSharedCSharpAssemblyVersionFile;
  24.                           WriteSharedCPPAssemblyVersionFile;
  25.                           WriteSharedWiXAssemblyVersionFile;"
  26.           Condition="('$(MSBuildProjectExtension)' == '.csproj') Or ('$(MSBuildProjectExtension)' == '.vbproj')">
  27.   </Target>
  28.  
  29.   <!-- Only use the named target if it's a C++ build, otherwise you get an MSBuild
  30.        warning MSB4057 about an non existant target. -->
  31.   <PropertyGroup Condition=" '$(MSBuildProjectExtension)' == '.vcxproj' ">
  32.     <CppResourceCompile>ResourceCompile</CppResourceCompile>
  33.   </PropertyGroup>
  34.   
  35.   <!-- For C++ projects, jam in the file creation before doing the Resource Compiler
  36.        build. -->
  37.   <Target Condition=" '$(MSBuildProjectExtension)' == '.vcxproj' "
  38.           Name="BuildVersionFiles"
  39.           BeforeTargets="$(CppResourceCompile)"
  40.           DependsOnTargets="WriteSharedTextAssemblyVersionFile;
  41.                             WriteSharedCSharpAssemblyVersionFile;
  42.                             WriteSharedCPPAssemblyVersionFile;
  43.                             WriteSharedWiXAssemblyVersionFile;">
  44.   </Target>
  45.  
  46. </Project>

Once everything is isolated into your VersionNumber.Targets file, you can include it with the following line in your .CSPROJ or .VCXPROJ file.

Import Example
  1. <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  2. <Import Project="..\Build\VersionNumbers.Targets"/>

A while ago, I showed using MSBuild 4.0 to create build version files with the TFS build number so that build number could be included in your binaries. While you can use Jim Lamb's excellent custom workflow activity, I liked doing the version numbers with MSBuild because you could have the same build for both the build server as well as the developer desktop.

Working with a client, they like my approach, but didn't care for the fact you had to initially create the assembly version files with a command line build. Additionally, there was good security and process on TFS build servers so adding the custom workflow activity was going to take a while to get installed. They asked me to get my pure MSBuild approach working inside Visual Studio projects so they could get the benefit of the build numbers, but not change how anyone builds the code on their development box. The client was kind enough to let me blog this so everyone could benefit. That and they wanted documentation on how I got it working. <grin!>

For the rest of this article, I'm assuming you've read my original blog entry on Wintellect.TFSBuildNumber.targets. I've put everything I discuss into a sample project that shows how to set this up for both C#/VB projects as well as for native C++ projects. You may want to grab the sample and look through it as you read along.

The job of Wintellect.TFSBuildNumbers.targets is to create files with build number information into them. You'll include those created files into your projects in order to get the version information, be it an AssemblyFileVersion attribute or a VERSIONINFO structure. Because the files that contain the version information should never be checked in, you need to create those files first thing or your build will fail. That means you'll need to do the steps I outline below in the first .CSPROJ/.VCSPROJ file built as part of your solution. Ideally, you'll only have to update a single project that every other binary depends on as described below to create the version files for your whole application. However, if you have various solutions and you don't know the order they will be built, it won't hurt to add these steps to all your projects as Wintellect.TFSBuildNumbers.targets only creates the build version files if they do not exist.

If you've got a C# .CSPROJ file as the first thing built, it's quite easy to integrate the version file creation code. To edit the .CSPROJ file by hand, click the File, Open, File, menu in Visual Studio.

In the PropertyGroup element that has no conditions on it, generally the first one after the Project element. You'll add the TFSMajorBuildNumber and TFSMinorBuildNumber elements with the appropriate values. By default Wintellect.TFSBuildNumbers.targets creates the shared files in the local directory so you should probably also set the SharedVersionOutputDirectory element to a common location. The following shows the first part of the .\BuildNumbers\VerFiles\VerFiles.CSPROJ file included with the sample.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
   xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{826C2BC7-70D3-4FE0-B4D8-0E1DE36E6D2E}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>VerFiles</RootNamespace>
    <AssemblyName>VerFiles</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>
    <!-- The following two properties are mandatory with
         Wintellect.TFSBuildNumber.targets-->
    <TFSMajorBuildNumber>22</TFSMajorBuildNumber>

    <TFSMinorBuildNumber>33</TFSMinorBuildNumber>
    <!-- The following property is optional with

         Wintellect.TFSBuildNumber.targets but you probably
         should always set it.-->

    <SharedVersionOutputDirectory>..\Shared</SharedVersionOutputDirectory>
  </PropertyGroup>
. . . Rest of file here . . .

With the properties out of the way, you'll scroll to the bottom of the .CSPROJ file where you will import the Wintellect.TFSBuildNumber.targets file with an Import element. C# projects have a nice target, BeforeBuild which is a target the build system will call before doing the actual build. You will need to add that target at the bottom of the file and use the DependsOnTargets to specify the various files you want to Wintellect.TFSBuildNumbers.targets to create.

Here the example of setting up the import and BeforeBuild target.

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- Include the targets that create the version number files. -->
  <Import Project="..\Targets\Wintellect.TFSBuildNumber.targets" />
  <!-- Define the BeforeBuild target, which is normally commented out,
       to depend on the particular version files I need created. -->
  <Target Name="BeforeBuild"
                DependsOnTargets="WriteSharedTextAssemblyVersionFile;
                                  WriteSharedCSharpAssemblyVersionFile;
                                  WriteSharedCPPAssemblyVersionFile;
                                  WriteSharedWiXAssemblyVersionFile;">
  </Target>
  <!-- To modify your build process, add your task inside one of the targets below
       and uncomment it.

       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

If you open the .\BuildNumbers\VerFiles\VerFiles.SLN and build it, you'll see four new files in the .\BuildNumbers\Shared directory. You'll also notice the project has a reference to the.\Shared\SharedAssemblyFileVersion.cs that was as a linked file. As a final reminder, because you'll be including the AssemblyFileVersion from Wintellect.TFSBuildNumber.targets, you'll need to manually remove any existing AssemblyFileVersion attributes in your projects.

Incorporating Wintellect.TFSBuildNumber.targets into a C++ project is similar to what you'll do for a C# project, but there's a little more fiddling going on. C++ is supposed to be harder than C#, so that's normal for the course. You can see a full example of setting up a C++ project in the .\BuildNumbers\CPPVerFiles directory in the sample download. The first step is to edit the .VCXPROJ file by hand to add the required properties with your major and minor versions. Look for the PropertyGroup element with the Label attribute set to Globals. Here's an example of setting up the properties.

  <PropertyGroup Label="Globals">
    <ProjectGuid>{B1CCCB99-E2C5-42BA-9680-8E9511CE81C7}</ProjectGuid>
    <RootNamespace>CPPVerFiles</RootNamespace>
    <Keyword>MFCProj</Keyword>

    <!-- The following two properties are needed by
         Wintellect.TFSBuildNumber.targets-->
    <TFSMajorBuildNumber>22</TFSMajorBuildNumber>
    <TFSMinorBuildNumber>33</TFSMinorBuildNumber>
    <!-- The following property writes the shared files to
         A different directory.—>
  <SharedVersionOutputDirectory>..\Shared</SharedVersionOutputDirectory>

</PropertyGroup>

At the bottom of your .VCXPROJ file, you'll need to import Wintellect.TFSBuildNumber.targets and hook the build number file creation into the build. As .VCXPROJ files do not have a predefined BeforeBuild target, it took me a little bit of trial and error to find where the best place to get my build number targets injected into the normal build flow. Fortunately, MSBuild 4.0 offers the BeforeTargets attribute on a target. As the build number files need to be created before the resource compiler runs, I chose to set the BeforeTargets to ResourceCompile. Here's the snippet that shows you what I'm talking about.

  <!-- Include the targets that create the version number files. -->
  <Import Project="..\Targets\Wintellect.TFSBuildNumber.targets" />

  <!-- Here's the trick to ensure the version files get built before
       they are needed by the resource compiler. -->
  <Target Name="BuildVersionFiles"
          BeforeTargets="ResourceCompile"
          DependsOnTargets="WriteSharedTextAssemblyVersionFile;
                            WriteSharedCSharpAssemblyVersionFile;
                            WriteSharedCPPAssemblyVersionFile;
                            WriteSharedWiXAssemblyVersionFile;">
  </Target>

</Project>

The above steps in the .VCXPROJ file take care of properly creating the files, but we need to get the version number into the binary. Because C++ code needs a VERSIONINFO structure in the resources file, you'll have to include a common one to pick up the build numbers. What I chose to do was have a common .RC file that's included in each of your project's .RC. Below is the .\CommonResources\CommonResources.RC you'll find in the sample.

#ifndef APSTUDIO_INVOKED

#include "..\Shared\SharedAssemblyFileVersion.h"

VS_VERSION_INFO VERSIONINFO
  FILEVERSION rcMajor,rcMinor,rcBuild,rcRevision
  PRODUCTVERSION rcMajor,rcMinor,rcBuild,rcRevision
  FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
  FILEFLAGS 0x1L
#else
  FILEFLAGS 0x0L
#endif
  FILEOS 0x4L
  FILETYPE 0x2L
  FILESUBTYPE 0x0L
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904e4"
    BEGIN
      VALUE "Comment", "De Oppresso Liber"
      VALUE "CompanyName", "Wintellect"
      VALUE "FileDescription", "Example of the common version resource file!"
      VALUE "FileVersion", szMajorMinorBuildRevision
      VALUE "InternalName", "SOMENAME"
      VALUE "LegalCopyright", "Copyright (c) 2011 by Wintellect"
      VALUE "ProductVersion", szMajorMinorBuildRevision
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x409, 1252
  END
END

#endif

To get this file into your project's .RC file, you'll edit it by hand in simply use #include to include the common file.

There are two key points I need to mention about getting a common resource file working. The first drove me nuts, but you want to include an actual resource, the including file must end with .RC. If you put it in a .H, the resource compiler silently ignores the contents of the file except for #define values. The second point was that I wanted to ensure that there was no way to edit the VERSIONFINO block in the Visual Studio Resource Editor. If that's allowed, the Resource Editor replaces all defines in the resource file with the current values of the build numbers. To avoid that problem, I wrap the common VERSIONINFO in #ifndef APPSTUDIO_INVOKE…#endif. The APPSTUDIO_INVOKE is the special define used to determine if the file is being edited by the Resource Editor. The old folks reading this will recall that the Resource Editor used to be called App Studio many years ago.

Some of you sharp readers might be wondering how you add non-shared data to the VERSIONINFO such as "OriginalFilename" and others as you can only have one VERSIONINFO structure per binary. If that private data is a required for your environment, add a new VALUE for it and before including the common resources, ensure you declare that define. Alternatively, you could use a VERSIONINFO editing tool like the Simple Version Resource Tool for Windows by ddbug as part of your build to add that information.

Based on the comments to my original article, this was a popular request, but I just never got around to doing it because I'm a command line guy and it wasn't a priority. Thanks to our client for pushing me to get build number creation working in projects and allowing me to share the result with everyone. Now there's no excuse for anyone to not have the build number show up when you look at a binary's properties.

Recently I bought a smoking fast external SSD enclosures from Other World Computing. My plan was to use the FireWire 800 connection to the drive so I can get the best portable speed possible. Alas, on all my machines as soon as I tried to do anything on the drive, Windows 7 hangs completely. That’s not good nor was the option of using that pokey USB 2 connection as that wouldn’t take advantage of the SSD drive.

Before I sent the drive back, I did some hard web searching and found I was not alone in people complaining about the Windows 7 FireWire drivers. Many people reported hangs, but none seemed to have a solution. Fortunately, John Zhu came to the rescue on the Tech Net Forums. Microsoft rewrote the IEEE 1394 (FireWire) driver for Windows 7 and let’s just say it doesn’t seem to work that well.

John pointed out that you could go into the Device Manager and change the driver to the 1394 Legacy driver. That’s worked great for me! It’s great to see those much faster speeds than USB 2. See John’s discussion for the exact steps to change the driver.

Everything in .NET revolves around memory. As in who in the heck is holding on to all my objects so memory usage just keeps going up and up and up. In conjunction with the Linked In .NET Users Group, on Friday, July 22, 2011 at 10:00 AM Pacific/1 PM Eastern, I'll be doing a demo only session on how to see the different ways of looking at your memory references. You'll see everything from WinDBG and SOS, to interesting commercial tools that show you the complete graph. The session is free and all you need to do is sign up here. If you're on Linked In, consider joining the Linked In .NET User Group as well.

If you like what I present, you can get much more at our upcoming Devscovery Austin event on October 18th-20th.

Deep down inside every developer really wants to create developer tools. Let’s be honest, how many of you are really excited to the tips of your toes about that Line of Business application you’re working on? It pays the bills but working on a project where you completely understand the target audience and all use cases really is a heck of a lot of fun!

As most developer tools are written as side work, it’s rare that on makes it to a level where they get used by anyone other than the developer themselves. The XteProfiler was one of those tools many are using. The developer,  Søren Skov Christensen, helped a lot of people find memory problems in their .NET application and he had a lot of fun developing XteProfiler. After a while of working on a tool, you reach a crossroads. You have a ton of ideas you want to put in the tool, but to do that you’ll have to quit your job. That’s where most tools stop and languish to everyone’s frustration and laments of “what could have been…”

Søren didn’t stop! He took the scary plunge and made the decision to go commercial with the new DRONE Profiler. He’s added a ton of fantastic features and DRONE is a complete package for your memory profiling needs. It’s also super exciting to see a developer follow their passion and take the risk to going out on their own. I highly encourage you to check out the new DRONE Profiler.

Disclosure: Even though Søren kindly gave me a license, I purchased my own license. DRONE Profiler is a damn good tool!

More Posts Next page »