Wednesday, June 19, 2013

Detect hardware in PC (windows) through C# code by Win32_PnPEntity and ManagementObjectSearcher

I was working with some hardware (Smart card reader), which needs to interact with my C# code. When I was starting, I was really a fresher in this area. My objective is to detect the device attached in my pc. If it is attached an event will fire, and same will happen on the remove. To do that, I created a windows service. But now the challenge is device detection on my pc.
To do that, I have to get the details from hardware manager of my pc. I got the solution from c# itself.
using System.Management;

It will help to get hardware information from pc using c# code. The code is as follows-
static bool getDeviceFromHWM(string deviceGuid)
        {
            ManagementObjectSearcher mos =
                   new ManagementObjectSearcher(@"\root\cimv2", @"Select * From Win32_PnPEntity WHERE ClassGuid = '"+deviceGuid+"'");


            ManagementObjectCollection moc = mos.Get();
            foreach (ManagementObject mo in moc)
            {

                PropertyDataCollection devsProperties = mo.Properties;
                foreach (PropertyData devProperty in devsProperties)
                {
                    if (devProperty.Type == CimType.DateTime)
                    {
                        if (devProperty.Value != null)
                        {
                                                    }
                    }
                    else
                    {
                        Console.WriteLine(" {0}----->{1}",devProperty.Name, devProperty.Value);
                    }
                }
            }
            if (moc.Count > 0)
                return true;
            else
                return false;
        }

Now, function receives one input “deviceGUID”. It is nothing but the device type id, common for windows. So , to find a smart card reader and smart card from my pc I have to use a GUID -{990a2bd7-e738-46c7-b26f-1cf8fb9f1391} and {50DD5230-BA8A-11D1-BF5D-0000F805F530}.

Basic Class GUID table

Class
GUID
Device Description
CDROM
4D36E965-E325-11CE-BFC1-08002BE10318
CD/DVD/Blu-ray drives
DiskDrive
4D36E967-E325-11CE-BFC1-08002BE10318
Hard drives
Display
4D36E968-E325-11CE-BFC1-08002BE10318
Video adapters
FDC
4D36E969-E325-11CE-BFC1-08002BE10318
Floppy controllers
FloppyDisk
4D36E980-E325-11CE-BFC1-08002BE10318
Floppy drives
HDC
4D36E96A-E325-11CE-BFC1-08002BE10318
Hard drive controllers
HIDClass
745A17A0-74D3-11D0-B6FE-00A0C90F57DA
Some USB devices
1394
6BDD1FC1-810F-11D0-BEC7-08002BE2092F
IEEE 1394 host controller
Image
6BDD1FC6-810F-11D0-BEC7-08002BE2092F
Cameras and scanners
Keyboard
4D36E96B-E325-11CE-BFC1-08002BE10318
Keyboards
Modem
4D36E96D-E325-11CE-BFC1-08002BE10318
Modems
Mouse
4D36E96F-E325-11CE-BFC1-08002BE10318
Mice and pointing devices
Media
4D36E96C-E325-11CE-BFC1-08002BE10318
Audio and video devices
Net
4D36E972-E325-11CE-BFC1-08002BE10318
Network adapters
Ports
4D36E978-E325-11CE-BFC1-08002BE10318
Serial and parallel ports
SCSIAdapter
4D36E97B-E325-11CE-BFC1-08002BE10318
SCSI and RAID controllers
System
4D36E97D-E325-11CE-BFC1-08002BE10318
System buses, bridges, etc.
USB
36FC9E60-C465-11CF-8056-444553540000
USB host controllers and hubs

Now, there is a problem, if we remove and add device very quickly. It will not update the status in system table. So, after removing a device from PC, it shows, device is still attached. To overcome the problem, I used following code-

public static class Win32Api
    {
        public const int CM_LOCATE_DEVNODE_NORMAL = 0x00000000;
        public const int CM_REENUMERATE_NORMAL = 0x00000000;
        public const int CR_SUCCESS = 0x00000000;

        [DllImport("CfgMgr32.dll", SetLastError = true)]
        public static extern int CM_Locate_DevNodeA(ref int pdnDevInst, string pDeviceID, int ulFlags);

        [DllImport("CfgMgr32.dll", SetLastError = true)]
        public static extern int CM_Reenumerate_DevNode(int dnDevInst, int ulFlags);
    }

And use it just at the beginning of your code-

int pdnDevInst = 0;

            if (Win32Api.CM_Locate_DevNodeA(ref pdnDevInst, null, Win32Api.CM_LOCATE_DEVNODE_NORMAL) != Win32Api.CR_SUCCESS) { }
          

            if (Win32Api.CM_Reenumerate_DevNode(pdnDevInst, Win32Api.CM_REENUMERATE_NORMAL) != Win32Api.CR_SUCCESS) { }



Full code-

public static void Main()
        {

int pdnDevInst = 0;

            if (Win32Api.CM_Locate_DevNodeA(ref pdnDevInst, null, Win32Api.CM_LOCATE_DEVNODE_NORMAL) != Win32Api.CR_SUCCESS) { }
          

            if (Win32Api.CM_Reenumerate_DevNode(pdnDevInst, Win32Api.CM_REENUMERATE_NORMAL) != Win32Api.CR_SUCCESS) { }
          

            if (getDeviceFromHWM("{50DD5230-BA8A-11D1-BF5D-0000F805F530}"))
                Console.WriteLine("Card reader is connected");

}
Further reference-


No comments: