Archive for the 'C#' Category

Lines between methods in the C# editor (CodeRush/DxCore plugin)

Like most .NET developers,  I used to do VB/VBA coding before C# came along. But, one thing I always missed in in the C# code editor was the lines that the VB editor puts between methods. An an avid user of CodeRush and Refactor! Pro, which itself does code structure painting in Visual Studio, I’ve created a DxCore Plugin that draws lines between methods which (IMHO) improves on the ones in the VB code editor.

Here’s a screen shot of it in action:

Draw Lines Between Methods - in action

And here’s the exciting options page:

Draw Lines Between Methods - settings

Even if you’re a VB.NET person you might like to try it to see if it works any better for you than VB’s built-in lines (although I guess you’d need to turn off the built-in method-separating lines somewhere in Tools Options).

As I wrote the code a while ago, it’s compiled as a .NET 1.1 DLL, so will work equally as well in Visual Studio 2003 as it does for me now in Visual Studio 2008.

Download (VS2003 source included): CR_DrawLinesBetweenMethods.zip

Let me know how you get on with it in the comments :)

Tests-behind: Tests as Code-Behind Files

One the first issues that you have to deal with when writing unit tests is - where do I put the the tests? Here’s where I prefer to have them: as close to the code that’s being tested as possible, like so:

tests behind 1

The tests class is hooked up to the original source file in the same way that ASP.NET code-behind files are, as a dependent project item.

You can do this by hacking the *csproj file directly using the <DependentUpon> tag, but to automate it I’ve written a Visual Studio macro (works in Visual Studio 2008, should work in Visual Studio 2005) that creates an appropriately-named tests class that can be invoked like so:

tests behind 2

Here’s the macro code (copy and paste into a code module in the Visual Studio Macros IDE: Tools > Macros > Macros IDE)

Sub AddTestsFile()
   Dim item As ProjectItem = DTE.SelectedItems.Item(1).ProjectItem
   Dim fileName As String = item.FileNames(1)
   Dim dir As String = System.IO.Path.GetDirectoryName(fileName)
   Dim bareName As String = System.IO.Path.GetFileNameWithoutExtension(fileName)
   Dim newItemPath As String = dir & "\" & bareName & ".Tests.cs"

   Dim codeClass As CodeClass = findClass(item.FileCodeModel.CodeElements)
   Dim namespaceName As String = codeClass.Namespace.FullName

   System.IO.File.WriteAllText(newItemPath, "" _
     & "#if DEBUG" & vbCrLf _
     & "using System;" & vbCrLf _
     & "using System.Diagnostics;" & vbCrLf _
     & "using NUnit.Framework;" & vbCrLf _
     & "" & vbCrLf _
     & "namespace " & namespaceName & vbCrLf _
     & "{" & vbCrLf _
     & "	[TestFixture]" & vbCrLf _
     & "	public class " & codeClass.Name & "_Tests" & vbCrLf _
     & "	{" & vbCrLf _
     & "		" & vbCrLf _
     & "	}" & vbCrLf _
     & "}" & vbCrLf _
     & "#endif" & vbCrLf _
    )

   ' Add as sub-item and show
   Dim newItem As ProjectItem = item.ProjectItems.AddFromFile(newItemPath)
   newItem.Open().Activate()

End Sub

' Utility used by AddTestsFile
Function findClass(ByVal items As System.Collections.IEnumerable) As CodeClass
   For Each codeEl As CodeElement In items
      If codeEl.Kind = vsCMElement.vsCMElementClass Then
         Return codeEl
      ElseIf codeEl.Children.Count > 0 Then
         Dim cls As CodeClass = findClass(codeEl.Children)
         If cls IsNot Nothing Then
            Return findClass(codeEl.Children)
         End If
      End If
   Next
   Return Nothing
End Function

(Note: WordPress is putting curly quotes in parts of the code, so you may need to find/replace them with straight quotes)

The right-click Project Item context menu shortcut can be wired up to the macro with the help of Sara Ford’s tip about customizing Visual Studio context menus.

Update 11 March 2008: Fixed findClass subroutine which resulted in null reference error, it now recurses correctly.

Shortcut to Switch User in Windows Vista

At home, our PC running Vista is rarely rebooted and is either in a low power state sleeping or being used by either me or my wife. One thing we’ve taken great advantage since the XP days is Fast User Switching which allows someone else to log in to their desktop whilst yours is kept running in the background. My wife and I had got quite used to doing a quick WinKey+L (as you do) before relinquishing control of the PC to one another. In Windows XP WinKey+L is does a “lock workstation” which in non-domain machines takes you back to the Windows logon screen. Unfortunately on Vista it takes you to a “workstation locked” screen, so you then have another mouse click on the Switch User button (followed by monitor re-syncing itself - why does it do this? All users run at the same screen resolution) to take you to the users screen. Of course there is a “Switch User” command tucked away in the little menu next to the lock button on the start menu - but a quick keystroke is what we’re after here.

So - I go off searching for a shortcut key that does a “switch user” rather than “lock workstation”. After a 20 minutes fruitless Googling for some special key combination, I sat back, thought about it logically and came up with this solution:

  1. Create a shortcut on your desktop to TSDISCON (* see below) and call it something like “Switch User”
  2. Go the shortcut Properties page and assign a shortcut key. Note that unfortunately you can’t use the Windows Key in your shortcut - so I went for CTRL + ALT + SHIFT + L
  3. Right click Start button and choose “Open All Users” and move the shortcut into the Programs folder (confirming the UAC prompt as you go).
  4. Log out, and back in again. This is necessary because Explorer hasn’t noticed there’s now a shortcut with a new shortcut key it should be taking notice of.

And that did it. CTRL + ALT + SHIFT + L isn’t quite a neat as WinKey+L but it’s a hell of a lot better than poking around in the Start Menu.

* What is TSDISCON you ask? It’s the Terminal Services Disconnect command. Fast User Switching is all made possible by the core Terminal Services technologies which introduced the concept of multiple Window Stations or “sessions” running concurrently on the one machine. It was of course originally designed to support multiple users connecting concurrently to these sessions over the network using the Remote Desktop Protocol (RDP), but Windows XP took advantage of the multi-session architecture to enable Fast User Switching. (The RDP stuff is still there but hobbled to only allow one user to connect at a a time.)

UPDATE: If you don’t have tsdiscon.exe on your system for some reason (maybe it’s only available in Business/Ultimate or something) then you can use the following C# code (compiled into a Windows EXE using C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe if you don’t have Visual Studio) to do the same thing. Tsdiscon.exe is just a wrapper around WTSDisconnectSession. I used Dependency Walker (aka depends.exe) to find out what was being used:

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

class Program
{
  [DllImport("wtsapi32.dll", SetLastError = true)]
  static extern bool WTSDisconnectSession(IntPtr hServer, int sessionId, bool bWait);

  const int WTS_CURRENT_SESSION = -1;
  static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;

  static void Main(string[] args)
  {
    if (!WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE,
         WTS_CURRENT_SESSION, false))
      throw new Win32Exception();
  }
}