Receiving "Hardware insertion or removal" is an interesting thing to consider while
programming in Windows. In fact, we may have already done this in our MFC or SDK applications. As
some of readers of my previous article suggested, I am trying to submit an
article here on Device Detection in C#.NET. The intention of the article is to
share the concepts which I found from other sources on the web. I hope this article
satisfies my intentions.
Calling Unmanaged Code from .NET
already know the .NET Framework is a development and execution environment that
allows different programming languages and libraries to work together
seamlessly to create Windows-based applications.
the breadth and depth of the .NET Framework, it cannot do everything. There are
times when you need to do something that is not covered by the Framework.
situation may occur in many scenarios, but the two most common contexts are:
- When there is some capability that you know is part
of the Windows API but is not yet in the .NET Framework.
- When you are programming an external device
whose drivers are written for the non-.NET programmer.
In both scenarios, our program will need to call
unmanaged code. More specifically, it needs to call code that is provided as
part of a dynamic link library or DLL; the Windows DLL in the first case, and a
manufacturer-provided DLL in the second.
code which is executing under the control of the runtime is called managed code.
Conversely, code that runs outside the runtime is called unmanaged code. COM
components, ActiveX interfaces, and Win32 API functions are examples of
How do we call functions in an unmanaged code DLL from your
managed code .NET program? This is achieved in .NET by a concept called
The Interop Service
This namespace provides a wide variety of members that support COM interop
and platform invoke services. This is our key to achieving device detection
keyword present in this namespace is used to import the unmanaged DLL of
context to our .NET application.
If we know the function name and
constants which are present in the unmanaged DLL, we can import all of them in
our .NET application.
an example, I will use the
Windows Sleep() function, which has the following
declaration (in C):
make this function accessible in your managed code, you would write the
DllImport statement like this:
static extern Boolean Sleep(
DllImport statement in our managed code, we can call the
like any other function:
Device detection in C#
Whenever a device arrival/removal
happens, Windows sends a message called
WM_DEVICECHANGE to all the applications
running currently in the system. But to receive this message our application
should handle the "Windows Process function". C# applications will not have
default support for this function; we need to explicitly override this method in
If we want to find the type of
the device inserted (specifically a USB mass storage) then we need to include
the structure which is defined in the unmanaged area.
For that we need to do marshalling. Marshalling
is a separate topic and there are lots of articles on this topic available on the net. So I
am simply going to show a sample.
public struct DEV_BROADCAST_VOLUME
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
protected override void WndProc(ref Message m)
const int WM_DEVICECHANGE = 0x0219;
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVECOMPLETE = 0x8001;
const int DBT_DEVTYP_VOLUME = 0x00000002;
int devType = Marshal.ReadInt32(m.LParam,4);
if(devType == DBT_DEVTYP_VOLUME)
vol = (DEV_BROADCAST_VOLUME)
base.WndProc (ref m);
Building the Sample Code
It is a simple C# Windows form application. Building the
sample code requires the Visual Studio.NET 2003 compiler. Execute the application
and insert/remove the USB Mass storage. The message box for device arrival and
removal will appear.