Check the Status of a Windows Service in C#

If you have an application that has a dependency on a Windows service, your application may need to be aware of the status of the service. Luckily, the .Net Framework makes this very easy for us to do.

Here’s how you can retrieve the status of a service:

var serviceName = "IISADMIN";
var sc = new ServiceController(serviceName);

Console.WriteLine("Status: {0}", sc.Status);

If you need your application to wait for a particular status, that’s very easy, too!

Console.WriteLine("Blocking until service is running...");
sc.WaitForStatus(ServiceControllerStatus.Running);

Note that WaitForStatus only blocks when the status doesn’t match the value provided. In other words, if the service in the above example is already running, it will not block.

More information about the ServiceController class can be found here.

Files as Embedded Resources in Unit Tests

One of the most common unit test mistakes that I see is using relative file paths to actual files. The problem with this is that tests run automatically as part of a build might not have the same file structure that your relative paths assume. A better solution is to use the DeploymentItem attribute in your tests to ensure the necessary resources are copied to the relevant unit test directory, but I prefer a different solution: compiling the files as embedded resources.

A file is added to the project as an embedded resource simply by changing its Build Action in Properties. Once it’s an embedded resource, it can be accessed from your unit tests like this:

private string GetFileContents(string sampleFile)
{
    var asm = Assembly.GetExecutingAssembly();
    var resource = string.Format("MyProject.Tests.SampleFiles.{0}", sampleFile);
    using (var stream = asm.GetManifestResourceStream(resource))
    {
        if (stream != null)
        {
            var reader = new StreamReader(stream);
            return reader.ReadToEnd();
        }
    }
    return string.Empty;
}

Note that the resource name is the Solution Explorer path to the file. So the above example is from a test project named “MyProject.Tests” in a folder named “SampleFiles.” This function accepts a file name and will return the contents of the specified file from that directory as a string.

This technique can be used in conjunction with mocks to simulate a multitude of scenarios like reading a file, retrieving data from a web service, or querying a database.

Here’s a quick example that demonstrates how this could be used to simulate retrieval of data from a web service:

public interface IDataAccess
{
	string GetXmlDataFromWebService();
}

public class MyClass
{
	private readonly IDataAccess _dataAccess;
	
	public MyClass(IDataAccess dataAccess)
	{
		_dataAccess = dataAccess;
	}
	
	public void Execute()
	{
		var xml = _dataAccess.GetXmlDataFromWebService();
		// do more...
	}
}

[TestMethod]
public void Execute_ProcessesXml()
{
	// Arrange
	var mockDataAccess = MockRepository.GenerateMock<IDataAccess>();
	var target = new MyClass(mockDataAccess);
	
	var xml = GetFileContents("TestData.xml");
	mockDataAccess.Expect(x => x.GetXmlDataFromWebService())
		.Return(xml);
	
	// Act
	target.Execute();
	
	// Assert
	mockDataAccess.VerifyAllExpectations();
	// more assertions...
}

Format Date/Time as UTC with Timezone Offset

Here’s a quick snippet from MSDN that demonstrates how to format a date/time to UTC format with a timezone offset. (ISO 8601 compliant!)

DateTime date1 = new DateTime(2008, 4, 10, 6, 30, 0);
DateTimeOffset dateOffset = new DateTimeOffset(date1,
    TimeZoneInfo.Local.GetUtcOffset(date1));
Console.Write(dateOffset.ToString("o"));

This will produce the following output:

2008-04-10T06:30:00.0000000-04:00

Everything you ever wanted to know and more about date and time formatting can be found here.

Print Recordset Details from IDataReader

Occasionally when working with recordsets returned by a stored procedure in an IDataReader, it can be helpful to print information about the columns returned. I like to do this when making a DTO class that mirrors a recordset to ensure that my class’s properties are typed consistently with the recordset. Printing the column details can be accomplished easily with the following code:

IDataReader reader = GetDataReader();
for (int i = 0; i < reader.FieldCount; i++)
{
    Console.WriteLine("Name:{0}, Type:{1}",
        reader.GetName(i),
        reader.GetDataTypeName(i));
}

Yield Keyword Explained

The yield keyword is a neat, but infrequently used, language feature of c#. Essentially, it allows you to “queue-up” results to be returned by a method as an enumerable collection.

Consider this simple example that produces a collection of integers from 0 to 9:

static IEnumerable<int> GetValues()
{
    var result = new List<int>();
    for (var i = 0; i < 10; i++)
    {
        result.Add(i);
    }
    return result;
}

By using yield, we can skip the step of creating a List<int> variable to store our results. This function will produce the same result:

static IEnumerable<int> GetValuesYieldEdition()
{
    for (var i = 0; i < 10; i++)
    {
        yield return i;
    }
}

IEnumerable to CSV Extension Method

I was talking with a co-worker about an efficient and reusable way to convert a list of objects to a comma-separated list of the objects’ IDs, and we came up with a pretty cool solution using an extension method. I figured I’d share — enjoy!

void Main()
{
       var x1 = new MyClass { Id = 1 };
       var x2 = new MyClass { Id = 2 };
       var x3 = new MyClass { Id = 3 };

       var myList = new List { x1, x2, x3 };

       var csv = myList.ToCsv();

       Console.WriteLine(csv);
}

public class MyClass
{
       public int Id {get;set;}
}

public static class MyClassExtensions
{
       public static string ToCsv(this IEnumerable<MyClass> myClasses)
       {
              return string.Join(",", myClasses.Select(x => x.Id));
       }
}

/*
Result:
1,2,3
*/

Windows Workflow 4: Adding Items to a Collection

I wanted to create a workflow that executes several custom activities in parallel and adds the results from each to a shared collection. This is easily accomplished by using WF4’s AddToCollection activity.

The XAML below demonstrates the use of both the Parallel and AddToCollection activities to accomplish this task. I’m also using of the ForEach activity to iterate through my collection to display the results.

<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib">
  <Sequence>
    <Sequence.Variables>
      <Variable x:TypeArguments="scg:List(x:String)" Default="[New List(Of String)]" Name="MyList" />
    </Sequence.Variables>

    <Parallel>
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item1" />
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item2" />
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item3" />
    </Parallel>
    
    <ForEach x:TypeArguments="x:String" Values="[MyList]">
        <ActivityAction x:TypeArguments="x:String">
            <ActivityAction.Argument>
                <DelegateInArgument x:TypeArguments="x:String" Name="item" />
            </ActivityAction.Argument>
            <WriteLine Text="[item]" />
        </ActivityAction>
    </ForEach>
  </Sequence>
</Activity>

Here’s the output produced by running this workflow:

Some notes about this example:

  • The XAML was written without the use of Visual Studio’s designer
  • There is a collection variable of type List<string> declared named “MyList”; this requires us to import the namespace System.Collections.Generic
  • The AddToCollection activities’ Collection properties are bound to MyList
  • The ForEach activity’s Values property is bound bound to MyList
  • The ForEach activity creates a delegate argument named “item” which is then passed in to the ForEach activity’s WriteLine activity

An Easy Fix for Registry Access for 32-bit Applications in 64-bit OSes

My company has a 32-bit application that is frequently run in a 64-bit environment. There are some registry settings retrieved by this application that exist in the WoW6432Node in a 64-bit OS, but how can we make our application smart enough to look there without breaking backward compatibility with 32-bit operating systems or sacrificing future compatibility if our application is converted to 64-bit?

One option is to implement a solution like what’s described here. You can add logic to your application to determine whether the OS is 32 or 64 bit and access the appropriate key.

That’s great, but it’s a lot of work for a setting in my application that’s read once during initialization. Instead of going through all that trouble, I just implemented a simple retry algorithm to look in Wow6432Node if the key isn’t found in the default expected location.

var regKey = GetRegistryKey(@"SOFTWARE\MyCompany\Settings");
if (regKey == null)
{
    regKey = GetRegistryKey(@"SOFTWARE\Wow6432Node\MyCompany\Settings");
    if (regKey == null)
    {
        throw new InvalidOperationException(
            @"Unable to find registry key HKLM\SOFTWARE\MyCompany\Settings");
    }
}

internal virtual RegistryKey GetRegistryKey(string path)
{
    return Registry.LocalMachine.OpenSubKey(
        path, 
        RegistryKeyPermissionCheck.ReadSubTree, 
        RegistryRights.ReadKey);
}

It’s simple and it works–terrific!

Add Additional References in LINQPad

LINQPad is one of my favorite development tools. I use it all the time to do quick tests to verify thoughts or discussions that I’m having with peers. It’s terrific for building snippets for email and doing quick what-is-this-really-doing checks. (And it’s perfectly free!)

One of the not-so-obvious things that I’ve run into with LINQPad is adding references. I looked through all the menus looking for some sort of “Add References” option but found nothing!

While slightly less obvious than I would’ve liked, adding references is very easy to do: just press F4. This is the keyboard shortcut to Query Properties–which can be found in the menus–where you can add additional assembly references or import namespaces.

I loves me some LINQPad!

Making Enumerable Collections LINQ-Queryable

LINQ is one of the greatest things that’s happened to Windows programming. I love it, and I use it all the time.

Occasionally, you’ll run into an enumerable collection class that can’t be queried with LINQ because it isn’t associated with a type. This can be easily overcome by using the Enumerable.Cast<T>() method.

Here’s a quick example from MSDN:

System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("apple");
fruits.Add("mango");

IEnumerable query =
	fruits.Cast().Select(fruit => fruit);

foreach (string fruit in query)
{
	Console.WriteLine(fruit);
}

This is a great technique to use instead of settling and using a for-each loop (ick!).