Resetting local Ports and Devices from .NET

Currently, I am working on C# applications that communicate with several external devices connected via USB ports. In rare cases the ports just stop working correctly, so we needed a programmatic approach to reset them. Doing this by using C# is not trivial. The solution we implemented uses the following components:
– C#’s SerialPort class
– WMI (Windows Management Instrumentation)
– P/Invoke with calls to the Windows Setup API

Accessing a port using C#
Using a certain port with C# is rather simple. The .NET framework provides the SerialPort class as a wrapper to the underlying Win32 port API. You can simply create a new instance of the class by providing the name of an existing port. On the instance object you have methods to open or close the port or to read and write data from its underlying stream. It also provides events to notify any listeners when data or errors were received. Here is a small example on how to open a port by first checking if the given port name exists in the operating system:


public SerialPort OpenPort(string portName)
{
if (!IsPortAvailable(portName))
{
return null;
}

var port = new SerialPort(portName);

try
{
port.Open();
}
catch (UnauthorizedAccessException) { ... }
catch (IOException) { ... }
catch (ArgumentException) { ... }
}

private bool IsPortAvailable(string portName)
{
// Retrieve the list of ports currently mounted by
// the operating system (sorted by name)
string[] ports = SerialPort.GetPortNames();
if (ports != null && ports.Length > 0)
{
return ports.Where(new Func((s) =>
{
return s.Equals(portName,
StringComparison.InvariantCultureIgnoreCase);
})).Count() == 1;
}
return false;
}

In rare cases the Open method of the port threw an IO Exception in our applications. This situation was not reproducible but also not acceptable. We noticed that after deactivating the port in the device manager and reactivating it, everything was working fine again. So we searched for a solution to do exactly the same thing from code.

Enable/Disable Devices
First of all a function or set of functions was needed to disable and enable a certain port. This can not directly be done from C# and needs some P/Invoke calls to the Win32 API. Luckily others had similar problems and so I found a very good solution at http://www.eggheadcafe.com/community/csharp/2/10315145/enabledisable-comm-port-by-programming.aspx. It uses the device installation functions from the Win32 Setup API. All you need is to retrieve the class GUID for the device set and the instance Id for the specific device you want to disable or enable. Just have a look at the link for the code or download the accompanying code for this blog post.

Retrieving the Ports Instance Id
Last thing to do is to acquire the correct instance Id for our port. We need a method that takes in the port name and retrieves the corresponding instance Id. For the exact definition of an instance Id in windows terms have a look at http://msdn.microsoft.com/en-us/library/windows/hardware/ff541224(v=vs.85).aspx. In our case we’d like to use the Plug ‘n’ Play device Id that can also be seen in the properties window of a device inside the device manager. For this purpose we are going to use WMI. If you need information about WMI have a look at http://msdn.microsoft.com/en-us/library/windows/desktop/aa394582(v=vs.85).aspx. WMI provides the Win32_SerialPort class that can be used to iterate over all mounted ports of the operating system. Two properties of the Win32_SerialPort class are important for us: The DeviceID property which represents the port name and the PNPDeviceID which gives the Plug ‘n’ Play instance Id. Notice while this works perfectly for Plug ‘n’ Play devices it may not work for other kinds of devices.

ManagementObjectSearcher searcher =
new ManagementObjectSearcher("select * from Win32_SerialPort");
foreach (ManagementObject port in searcher.Get())
{
if (port["DeviceID"].ToString().Equals(portName))
{
instanceId = port["PNPDeviceID"].ToString();
break;
}
}

If we found the appropriate instance Id we can use it together with the Win32 Setup API to retrieve a device info set and the corresponding device info data. If a device info for the instance Id was found we can use its class GUID and the instance Id to disable and enable the device. The following method is used to reset a port with a given instance Id:

public static bool TryResetPortByInstanceId(string instanceId)
{
SafeDeviceInfoSetHandle diSetHandle = null;
if (!String.IsNullOrEmpty(instanceId))
{
try
{
Guid[] guidArray = GetGuidFromName("Ports");

//Get the handle to a device information set for all
//devices matching classGuid that are present on the
//system.
diSetHandle = NativeMethods.SetupDiGetClassDevs(
ref guidArray[0],
null,
IntPtr.Zero,
SetupDiGetClassDevsFlags.DeviceInterface);

//Get the device information data for each matching device.
DeviceInfoData[] diData = GetDeviceInfoData(diSetHandle);

//Try to find the object with the same instance Id.
foreach (var infoData in diData)
{
var instanceIds =
GetInstanceIdsFromClassGuid(infoData.ClassGuid);
foreach (var id in instanceIds)
{
if (id.Equals(instanceId))
{
//disable port
SetDeviceEnabled(infoData.ClassGuid, id, false);
//wait some milliseconds
Thread.Sleep(200);
//enable port
SetDeviceEnabled(infoData.ClassGuid, id, true);
return true;
}
}
}
}
catch (Exception)
{
return false;
}
finally
{
if (diSetHandle != null)
{
if (diSetHandle.IsClosed == false)
{
diSetHandle.Close();
}
diSetHandle.Dispose();
}
}
}
return false;
}

With the code set up so far we can now easily reset a port in case we’re getting an IO Exception while trying to open the port. We just have to call the method inside our exception handler and try to open the port again. That solved our initial problem. Be aware that it may take some time to disable and re-enable the port. It may be a good idea to do it inside a separate thread if you’re working inside an application using a GUI.

C# Operator Overloading for Improved Code Readability

In this blog post I’m going to show you some basic stuff concerning operator overloading in C#. Operators can be very useful in situations where you want to write elegant and easy to understand code by using standard C# syntax. For this post I will use a simple API that creates Crystal Reports selection formulas out of a given DataSet and some operators.

Introduction: Crystal Syntax
In order to understand why operators perfectly fit this usage scenario we need to have a short glimpse at the Crystal syntax for selection formulas. Selection formulas enable you to filter the displayed data inside a Crystal Reports report according to the underlying data. Often you use a dataset and bind it to a report which in turn gets shown in the Crystal Reports Viewer. Formulas are given as pure strings, so if you want to use the programmatically you have to learn Crystal Syntax which is not really fun. Let’s have a look at the basic concepts:

Column References
References to Columns of the underlying data source are written as {TableName.ColumnName}. So if you have a dataset with a table called Customer and a Column called name, you would write {Customer.Name}.

Comparison Operators
You can use comparison operators in order to compare a column value to any given value. Beneath the standard comparison operators like ‘less than’ or ‘greater than’ or ‘equals’ you also have some string operators like ‘starts with’ or ‘like’. So you could write something like the following: {Customer.Name} startswith ‘A’.

Boolean Operators
Simple Expressions like the one shown above can be concatenated by using Boolean operators. Crystal Reports supports Not, And, Or, Xor, Eqv and Imp. Here’s an example: {Customer.Name} startsWith ‘A’ and {Customer.Age} < 18.

I think that’s enough for the moment to get started. If you want to see more operators or want to play around with selection formulas use the formula editor of the Crystal Reports designer in Visual Studio.

Crystal Syntax Converter
I don’t feel comfortable writing magic strings in code without getting them checked by some instance. Selection formulas can become very complex and error prone. So I searched for a solution to write down C# code and get the string generated out of it. My first approach was some kind of fluent API, so I could write something like the following:

Customer.NameColumn.StartsWith(“A”).And(Customer.AgeColumn.LessThan(18))

The result of this expression is equivalent to the Boolean Operators example above. But it’s much longer and more difficult to read. So I dropped that approach and turned to operator overloading. As stated at the beginning, operators are very powerful when used in appropriate situations. For our example we need to overload binary operators in order to get boolean operators and of course the comparison operators.

Let’s start with the very simplest expression. We want to use a column of our data source and compare it to any other value (e.g. a string or number). I start by writing a simple extension method, because I don’t want to write down DataSet.Table.Column every time and I need a custom object where I can define the overloaded operators. The custom class will be called CrystalColumn and the extension method looks like this:

public static CrystalColumn ToCrystalColumn(this DataColumn dc)
{
var sb = new StringBuilder("{");
sb.Append(dc.Table.TableName);
sb.Append(".");
sb.Append(dc.ColumnName);
sb.Append("}");

return new CrystalColumn(sb.ToString());
}

The method simply takes in a DataColumn and creates a string representation of it according to the Crystal Syntax. So now we a are able to write:

var firstname = dataSet.Customer
.FirstNameColumn.ToCrystalColumn();

The next step would be to overload the needed operators on the CrystalColumn class. Here’s the example of the ‘less than’ operator:

public static SingleExpression operator <(CrystalColumn column, int value)
{
return new SingleExpression(column.ToString() + " < " + value);
}

The method needs to be static and the first parameter depicts the object on which the operator is defined. The provided objects are converted to the according string representation and passed to a new instance of the SingleExpression class. This class encapsulates a simple expression. With the code so far we can write the following:

var age = dataSet.Customer.AgeColumn.ToCrystalColumn();
var singleExpression = age 1)
{
startsWithExpression = "[";
for (int i = 0; i < s.Length; i++)
{
startsWithExpression += "'" + s[i] + "'";
if (i < s.Length - 1)
startsWithExpression += ",";
}
startsWithExpression += "]";
}

var expression = columnExpression + " startswith " + startsWithExpression;
return new SingleExpression(expression);
}

The ’starts with’ operator in Crystal Reports acceppts an array of strings. That’s why the method acceppts a string array as parameter. Again a string represenation of the provided objects is created and passed to a new instance of the SingleExpression class. This method allows us to write:

var firstname = dataSet.Customer.FirstNameColumn.ToCrystalColumn();
var singleExpression = firstname.StartsWith("Mike", "John");

What’s missing now is the ability to combine two or more simple expressions by employing boolean operators to form complex expressions. In order to achieve this, we can now overload the needed binary operators on the SingleExpression class. For example the ‘And’ operator can be overloaded as follows:

public static Expression operator &(SingleExpression ex1, SingleExpression ex2)
{
return ex1.And(ex2);
}

private Expression And(SingleExpression singleExpression)
{
return new Expression(this,
singleExpression, LogicalOperator.and);
}

The operator overload takes a second SingleExpression instance and calls the private ‘And’ method. This method in turn creates a new Expression instance that encapsulates two or more simple expressions and finally generates the needed string representation. As another example I will show you the implementation of the ‘Not’ operator:

public static SingleExpression operator !(SingleExpression ex)
{
return new SingleExpression(
"not (" + ex.ToString() + ")");
}

The method takes only one argument, because the ’Not’ operator is an unary operator acting on a single argument. According to this only a simple expression is returned.

Putting it all together
With the classes and method we have so far, we can now write our example expression using operators:

var firstname = dataSet.Customer.FirstNameColumn.ToCrystalColumn();
var age = dataSet.Customer.AgeColumn.ToCrystalColumn();

var expression = firstname.StartsWith("A", "B") & age < 18;

When you compare that statement to the first approach, I think it’s easy to see that the readability improved a lot. We can also compare it to the resulting formula in Crystal Syntax and see that it is as nearly as short as the formula:

{Customer.FirstName} startswith [‘A’,’B’] and {Customer.Age} < 18

The Expression class overwrites its ToString method in order to write out the complete selection formula, so you can now easily pass it to the report viewer:

crystalViewer.SelectionFormula = expression.ToString();

Summary
This was only a short example of operator overloading in C# but I hope you noticed the great benefit of using them. If you need more information about C# operators just search the internet. It’s not a new concept. Some words of wisdom: Operators are not reasonable in every situation. Additionally when you use them be sure to use them the correct way and implement only operations that act the way a user would expect them to do. If you for example implement the ‘+’ operator for a custom number class, don’t return the difference. People are anticipating the results of common operations and get confused if something strange happens.