您的位置:首页 > 编程语言 > C#

通过API实现C#对硬件的控制(二)

2008-02-08 12:16 537 查看
通过上一篇“通过API实现C#对硬件的控制(一)” 我们掌握了我们所需要的相关API知识点。为此,我们现在来构建我们自己的外部调用类:Externs。由于有上一篇的详细说明,该处不再一一说明相关的函数知识点。

下面是该类的代码:


using System;


using System.Collections.Generic;


using System.Text;


using System.Runtime.InteropServices;




namespace Hardware




...{




/**//// <summary>


/// 下列所需函数可参考MSDN中与驱动程序相关的API函数


/// </summary>


public class Externs




...{


public const int DIGCF_ALLCLASSES = (0x00000004);


public const int DIGCF_PRESENT = (0x00000002);


public const int INVALID_HANDLE_VALUE = -1;


public const int SPDRP_DEVICEDESC = (0x00000000);


public const int MAX_DEV_LEN = 1000;


public const int DEVICE_NOTIFY_WINDOW_HANDLE = (0x00000000);


public const int DEVICE_NOTIFY_SERVICE_HANDLE = (0x00000001);


public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = (0x00000004);


public const int DBT_DEVTYP_DEVICEINTERFACE = (0x00000005);


public const int DBT_DEVNODES_CHANGED = (0x0007);


public const int WM_DEVICECHANGE = (0x0219);


public const int DIF_PROPERTYCHANGE = (0x00000012);


public const int DICS_FLAG_GLOBAL = (0x00000001);


public const int DICS_FLAG_CONFIGSPECIFIC = (0x00000002);


public const int DICS_ENABLE = (0x00000001);


public const int DICS_DISABLE = (0x00000002);






/**//// <summary>


/// 注册设备或者设备类型,在指定的窗口返回相关的信息


/// </summary>


/// <param name="hRecipient"></param>


/// <param name="NotificationFilter"></param>


/// <param name="Flags"></param>


/// <returns></returns>


[DllImport("user32.dll", CharSet = CharSet.Auto)]


public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, DEV_BROADCAST_DEVICEINTERFACE NotificationFilter, UInt32 Flags);






/**//// <summary>


/// 通过名柄,关闭指定设备的信息。


/// </summary>


/// <param name="hHandle"></param>


/// <returns></returns>


[DllImport("user32.dll", CharSet = CharSet.Auto)]


public static extern uint UnregisterDeviceNotification(IntPtr hHandle);






/**//// <summary>


/// 获取一个指定类别或全部类别的所有已安装设备的信息


/// </summary>


/// <param name="gClass"></param>


/// <param name="iEnumerator"></param>


/// <param name="hParent"></param>


/// <param name="nFlags"></param>


/// <returns></returns>


[DllImport("setupapi.dll", SetLastError = true)]


public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, UInt32 iEnumerator, IntPtr hParent, UInt32 nFlags);






/**//// <summary>


/// 销毁一个设备信息集合,并且释放所有关联的内存


/// </summary>


/// <param name="lpInfoSet"></param>


/// <returns></returns>


[DllImport("setupapi.dll", SetLastError = true)]


public static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);






/**//// <summary>


/// 枚举指定设备信息集合的成员,并将数据放在SP_DEVINFO_DATA中


/// </summary>


/// <param name="lpInfoSet"></param>


/// <param name="dwIndex"></param>


/// <param name="devInfoData"></param>


/// <returns></returns>


[DllImport("setupapi.dll", SetLastError = true)]


public static extern bool SetupDiEnumDeviceInfo(IntPtr lpInfoSet, UInt32 dwIndex, SP_DEVINFO_DATA devInfoData);






/**//// <summary>


/// 获取指定设备的属性


/// </summary>


/// <param name="lpInfoSet"></param>


/// <param name="DeviceInfoData"></param>


/// <param name="Property"></param>


/// <param name="PropertyRegDataType"></param>


/// <param name="PropertyBuffer"></param>


/// <param name="PropertyBufferSize"></param>


/// <param name="RequiredSize"></param>


/// <returns></returns>


[DllImport("setupapi.dll", SetLastError = true)]


public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr lpInfoSet, SP_DEVINFO_DATA DeviceInfoData, UInt32 Property, UInt32 PropertyRegDataType, StringBuilder PropertyBuffer, UInt32 PropertyBufferSize, IntPtr RequiredSize);






/**//// <summary>


/// 停用设备


/// </summary>


/// <param name="DeviceInfoSet"></param>


/// <param name="DeviceInfoData"></param>


/// <param name="ClassInstallParams"></param>


/// <param name="ClassInstallParamsSize"></param>


/// <returns></returns>


[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]


public static extern bool SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, IntPtr ClassInstallParams, int ClassInstallParamsSize);






/**//// <summary>


/// 启用设备


/// </summary>


/// <param name="InstallFunction"></param>


/// <param name="DeviceInfoSet"></param>


/// <param name="DeviceInfoData"></param>


/// <returns></returns>


[DllImport("setupapi.dll", CharSet = CharSet.Auto)]


public static extern Boolean SetupDiCallClassInstaller(UInt32 InstallFunction, IntPtr DeviceInfoSet, IntPtr DeviceInfoData);






/**//// <summary>


/// RegisterDeviceNotification所需参数


/// </summary>


[StructLayout(LayoutKind.Sequential)]


public struct DEV_BROADCAST_HANDLE




...{


public int dbch_size;


public int dbch_devicetype;


public int dbch_reserved;


public IntPtr dbch_handle;


public IntPtr dbch_hdevnotify;


public Guid dbch_eventguid;


public long dbch_nameoffset;


public byte dbch_data;


public byte dbch_data1;


}




// WM_DEVICECHANGE message


[StructLayout(LayoutKind.Sequential)]


public class DEV_BROADCAST_DEVICEINTERFACE




...{


public int dbcc_size;


public int dbcc_devicetype;


public int dbcc_reserved;


}






/**//// <summary>


/// 设备信息数据


/// </summary>


[StructLayout(LayoutKind.Sequential)]


public class SP_DEVINFO_DATA




...{


public int cbSize;


public Guid classGuid;


public int devInst;


public ulong reserved;


};






/**//// <summary>


/// 属性变更参数


/// </summary>


[StructLayout(LayoutKind.Sequential)]


public class SP_PROPCHANGE_PARAMS




...{


public SP_CLASSINSTALL_HEADER ClassInstallHeader = new SP_CLASSINSTALL_HEADER();


public int StateChange;


public int Scope;


public int HwProfile;


};






/**//// <summary>


/// 设备安装


/// </summary>


[StructLayout(LayoutKind.Sequential)]


public class SP_DEVINSTALL_PARAMS




...{


public int cbSize;


public int Flags;


public int FlagsEx;


public IntPtr hwndParent;


public IntPtr InstallMsgHandler;


public IntPtr InstallMsgHandlerContext;


public IntPtr FileQueue;


public IntPtr ClassInstallReserved;


public int Reserved;


[MarshalAs(UnmanagedType.LPTStr)]


public string DriverPath;


};




[StructLayout(LayoutKind.Sequential)]


public class SP_CLASSINSTALL_HEADER




...{


public int cbSize;


public int InstallFunction;


};


}


}



在完成了该类后,我们还需要写一个对硬件操作与获取的操作类HardwareClass。

下面为它的完整代码:


using System;


using System.Collections.Generic;


using System.Text;


using System.Runtime.InteropServices;




namespace Hardware




...{


public class HardwareClass




...{




属性#region 属性




/**//// <summary>


/// 返回所有硬件信息列表


/// </summary>


/// <returns></returns>


public string[] List




...{


get




...{


List<string> HWList = new List<string>();


try




...{


Guid myGUID = System.Guid.Empty;


IntPtr hDevInfo = Externs.SetupDiGetClassDevs(ref myGUID, 0, IntPtr.Zero, Externs.DIGCF_ALLCLASSES | Externs.DIGCF_PRESENT);


if (hDevInfo.ToInt32() == Externs.INVALID_HANDLE_VALUE)




...{


throw new Exception("Invalid Handle");


}


Externs.SP_DEVINFO_DATA DeviceInfoData;


DeviceInfoData = new Externs.SP_DEVINFO_DATA();


DeviceInfoData.cbSize = 28;


DeviceInfoData.devInst = 0;


DeviceInfoData.classGuid = System.Guid.Empty;


DeviceInfoData.reserved = 0;


UInt32 i;


StringBuilder DeviceName = new StringBuilder("");


DeviceName.Capacity = Externs.MAX_DEV_LEN;


for (i = 0; Externs.SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)




...{


while (!Externs.SetupDiGetDeviceRegistryProperty(hDevInfo, DeviceInfoData, Externs.SPDRP_DEVICEDESC, 0, DeviceName, Externs.MAX_DEV_LEN, IntPtr.Zero))




...{


//Skip


}


HWList.Add(DeviceName.ToString());


}


Externs.SetupDiDestroyDeviceInfoList(hDevInfo);


}


catch (Exception ex)




...{


throw new Exception("枚举设备列表出错", ex);


}


return HWList.ToArray();


}


}




#endregion






公共事件#region 公共事件




/**//// <summary>


/// 清理非托管资源


/// </summary>


/// <param name="callback"></param>


public void Dispose(IntPtr callback)




...{


try




...{


Externs.UnregisterDeviceNotification(callback);


}


catch




...{


}


}






/**//// <summary>


/// 设置指定设备的状态


/// </summary>


/// <param name="match">设备名称</param>


/// <param name="bEnable">是否启用</param>


/// <returns></returns>


public bool SetState(string[] match, bool bEnable)




...{


try




...{


Guid myGUID = System.Guid.Empty;


IntPtr hDevInfo = Externs.SetupDiGetClassDevs(ref myGUID, 0, IntPtr.Zero, Externs.DIGCF_ALLCLASSES | Externs.DIGCF_PRESENT);


if (hDevInfo.ToInt32() == Externs.INVALID_HANDLE_VALUE)




...{


return false;


}


Externs.SP_DEVINFO_DATA DeviceInfoData;


DeviceInfoData = new Externs.SP_DEVINFO_DATA();


DeviceInfoData.cbSize = 28;


DeviceInfoData.devInst = 0;


DeviceInfoData.classGuid = System.Guid.Empty;


DeviceInfoData.reserved = 0;


UInt32 i;


StringBuilder DeviceName = new StringBuilder("");


DeviceName.Capacity = Externs.MAX_DEV_LEN;


for (i = 0; Externs.SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)




...{


while (!Externs.SetupDiGetDeviceRegistryProperty(hDevInfo, DeviceInfoData, Externs.SPDRP_DEVICEDESC, 0, DeviceName, Externs.MAX_DEV_LEN, IntPtr.Zero))




...{


}


bool bMatch = true;


foreach (string search in match)




...{


if (!DeviceName.ToString().ToLower().Contains(search.ToLower()))




...{


bMatch = false;


break;


}


}


if (bMatch)




...{


OpenClose(hDevInfo, DeviceInfoData, bEnable);


}


}


Externs.SetupDiDestroyDeviceInfoList(hDevInfo);


}


catch (Exception ex)




...{


throw new Exception("枚举设备信息出错!", ex);


return false;


}


return true;


}






/**//// <summary>


/// 允许一个窗口或者服务接收所有硬件的通知


/// 注:目前还没有找到一个比较好的方法来处理如果通知服务。


/// </summary>


/// <param name="callback"></param>


/// <param name="UseWindowHandle"></param>


/// <returns></returns>


public bool AllowNotifications(IntPtr callback, bool UseWindowHandle)




...{


try




...{


Externs.DEV_BROADCAST_DEVICEINTERFACE dbdi = new Externs.DEV_BROADCAST_DEVICEINTERFACE();


dbdi.dbcc_size = Marshal.SizeOf(dbdi);


dbdi.dbcc_reserved = 0;


dbdi.dbcc_devicetype = Externs.DBT_DEVTYP_DEVICEINTERFACE;


if (UseWindowHandle)


Externs.RegisterDeviceNotification(callback, dbdi, Externs.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | Externs.DEVICE_NOTIFY_WINDOW_HANDLE);


else


Externs.RegisterDeviceNotification(callback, dbdi, Externs.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | Externs.DEVICE_NOTIFY_SERVICE_HANDLE);


return true;


}


catch (Exception ex)




...{


string err = ex.Message;


return false;


}


}




#endregion






私有事件#region 私有事件




/**//// <summary>


/// 开启或者关闭指定的设备驱动


/// 注意:该方法目前没有检查是否需要重新启动计算机。^.^


/// </summary>


/// <param name="hDevInfo"></param>


/// <param name="devInfoData"></param>


/// <param name="bEnable"></param>


/// <returns></returns>


private bool OpenClose(IntPtr hDevInfo, Externs.SP_DEVINFO_DATA devInfoData, bool bEnable)




...{


try




...{


int szOfPcp;


IntPtr ptrToPcp;


int szDevInfoData;


IntPtr ptrToDevInfoData;


Externs.SP_PROPCHANGE_PARAMS SP_PROPCHANGE_PARAMS1 = new Externs.SP_PROPCHANGE_PARAMS();


if (bEnable)




...{


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Externs.SP_CLASSINSTALL_HEADER));


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.InstallFunction = Externs.DIF_PROPERTYCHANGE;


SP_PROPCHANGE_PARAMS1.StateChange = Externs.DICS_ENABLE;


SP_PROPCHANGE_PARAMS1.Scope = Externs.DICS_FLAG_GLOBAL;


SP_PROPCHANGE_PARAMS1.HwProfile = 0;




szOfPcp = Marshal.SizeOf(SP_PROPCHANGE_PARAMS1);


ptrToPcp = Marshal.AllocHGlobal(szOfPcp);


Marshal.StructureToPtr(SP_PROPCHANGE_PARAMS1, ptrToPcp, true);


szDevInfoData = Marshal.SizeOf(devInfoData);


ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);




if (Externs.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(Externs.SP_PROPCHANGE_PARAMS))))




...{


Externs.SetupDiCallClassInstaller(Externs.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);


}


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Externs.SP_CLASSINSTALL_HEADER));


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.InstallFunction = Externs.DIF_PROPERTYCHANGE;


SP_PROPCHANGE_PARAMS1.StateChange = Externs.DICS_ENABLE;


SP_PROPCHANGE_PARAMS1.Scope = Externs.DICS_FLAG_CONFIGSPECIFIC;


SP_PROPCHANGE_PARAMS1.HwProfile = 0;


}


else




...{


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Externs.SP_CLASSINSTALL_HEADER));


SP_PROPCHANGE_PARAMS1.ClassInstallHeader.InstallFunction = Externs.DIF_PROPERTYCHANGE;


SP_PROPCHANGE_PARAMS1.StateChange = Externs.DICS_DISABLE;


SP_PROPCHANGE_PARAMS1.Scope = Externs.DICS_FLAG_CONFIGSPECIFIC;


SP_PROPCHANGE_PARAMS1.HwProfile = 0;


}


szOfPcp = Marshal.SizeOf(SP_PROPCHANGE_PARAMS1);


ptrToPcp = Marshal.AllocHGlobal(szOfPcp);


Marshal.StructureToPtr(SP_PROPCHANGE_PARAMS1, ptrToPcp, true);


szDevInfoData = Marshal.SizeOf(devInfoData);


ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);


Marshal.StructureToPtr(devInfoData, ptrToDevInfoData, true);




bool rslt1 = Externs.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(Externs.SP_PROPCHANGE_PARAMS)));


bool rstl2 = Externs.SetupDiCallClassInstaller(Externs.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);


if ((!rslt1) || (!rstl2))




...{


throw new Exception("不能更改设备状态。");


return false;


}


else




...{


return true;


}


}


catch (Exception ex)




...{


return false;


}


}




#endregion


}


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: