c#中如何实现并行处理处理WM

Process类的CloseMainWindow, Kill, Close
Process.CloseMainWindow是GUI程序的最友好结束方式,从名字上就可以看出来它是通过结束主窗体,相当于用户点击窗体的关闭按钮或者按Alt + F4。它的本质就是向主窗体发送WM_CLOSE消息(Process.MainWindowsHandle可以返回主窗体的句柄)。这个可以在.NET Framework源代码中看出来:
publicbool CloseMainWindow()
IntPtr mainWindowHandle =this.MainWindowH
//句柄是否为0
if (mainWindowHandle ==IntPtr.Zero)
returnfalse;
//GetWindowLong是否成功执行
if ((NativeMethods.GetWindowLong(newHandleRef(this, mainWindowHandle), -16) &0x8000000) !=0)
returnfalse;
//0x10 是 WM_CLOSE消息
//向主窗体发送WM_CLOSE,注意是PostMessage而不是SendMessage
NativeMethods.PostMessage(newHandleRef(this, mainWindowHandle), 0x10, IntPtr.Zero, IntPtr.Zero);
returntrue;
CloseMainWindow方法使用PostMessage(不是SendMessage,所以消息会加在消息队列的最后)方法向主窗体发送一个WM_CLOSE消息,这样等主窗体处理完所有消息后,等遇到WM_CLOSE便开始执行退出动作。
比如记事本接到了WM_CLOSE消息但是有未保存的文件记事本会弹出对话框提示用户保存还是不保存还是取消退出操作。Windows Forms和WPF的窗体都会有类似操作,通过窗体的Closing事件来在WM_CLOSE消息接收后做出是否退出的决定。
之后我们会讲到Windows Forms和WPF都有自己的友好型常规退出方式,但是其实有一个通用的GUI程序退出方式,就是利用这个CloseMainWindow方法:
//Windows Forms和WPF都可以用
//Windows Forms的Form.Closing事件会在之后发生
//WPF的Windows.Closing事件也会
Process.GetCurrentProcess().CloseMainWindow();
接下来就是Process.Kill方法,从名字也可以看出来,直接杀掉,不给喘息喘息机会呵呵。Kill方法会直接结束整个进程,不进行常规资源清理(什么finally块等&&)。Kill本质调用本地API:TerminateProcess函数。
最后一个是Process.Close方法。抱歉它根本不是用来结束进程的!这个方法名字有些误导,其实根本则不然。它仅仅是而是IDisposable的Dispose方法的具体执行,用来进行Process类的托管资源清理的!
由于Process类继承自Component类,后者继承IDisposable而同时又有析构函数,而通过一个继承类可改写的Dispose方法(参数是bool disposing)来判断这个Dispose是用户调用还是GC调用。而这个Process.Close()方法正是用户调用Dispose时进行托管资源的清理方法:
下面Process.Dispose方法代码:
protectedoverridevoid Dispose(bool disposing)
if (!this.disposed)
if (disposing)
//用户调用,清理托管资源
this.Close();
this.disposed =true;
//调用Component的Dispose
base.Dispose(disposing);
这个Close方法类似很多其他.NET中的类,比如Stream&&因此Close肯定不会结束进程,仅仅是Process类作为IDisposable接口的间接继承者的自我清理方法。
Environment类的Exit和FailFast
Environment.Exit相当于在Main函数中的return指令。不过它不会执行代码块的finally块(如果有的话),但资源清理还是要进行的。
它是最常见的退出当前进程的方法之一。在Main函数中我们可以直接return语句便退出了程序。如果不在Main函数内,那么Environment.Exit方法就可以派上用场:
Console.WriteLine("析构函数");
classProgram
staticvoid Main()
a oa =newa();
//这段代码永远不会执行
Console.WriteLine("finally");
staticvoid test()
Environment.Exit(0);
代码将会输出:
看来GC调用了oa的析构函数,但注意finally块没有运行。
Environment.FailFast方法更速度,它甚至不需要向操作系统返回进程退出代码(ExitCode),直接结束当前进程并在应用程序事件薄中写入信息,用于程序出现致命错误需要立即停止。
Console.WriteLine("析构函数");
classProgram
staticvoid Main()
a oa =newa();
Environment.FailFast("致命错误发生!");
//这段代码永远不会执行
Console.WriteLine("finally");
在.NET 4.0下,Environment.FailFast代码会抛出FatalExecutionEngineError,而在4.0之前会抛出ExecutionEngineException。但都不会有任何输出(GC没有清理对象,同时finally块也没有运行)
WPF的Shutdown和Windows Forms的Exit
GUI程序往往都有自己的消息队列和事件管理模式,因此结束一个GUI程序要远复杂与结束一个控制台程序。上述的方法中,Process.Kill和Environment.Exit和FailFast如果用在一个GUI程序中,都会直接强制结束整个程序,而不会激发GUI窗体的一些针对应用程序结束的事件(比如Closing事件)。而上面也讲过:Process.CloseMainWindow通过向主窗体发送一个WM_CLOSE消息可以很好的结束一个GUI程序,不过往往更自然的方法是利用GUI框架本身提供的结束程序的方法。
WPF中是System.Windows.Application.Shutdown方法,它其实就是在当前线程的消息队列Dispatcher对象中加入一个正常优先级(DispatcherPriority.Normal)的回调退出函数,等消息队列最后处理到该项时程序开始退出操作。通常这样使用:
//或者App也可以,WPF程序默认会有一个App类继承Application类
Application.Current.Shutdown();
Windows Forms中是:System.Windows.Forms.Application.Exit方法。它是通过Application.OpenFormsInternal属性先把已经打开的窗体通过正常方式都关闭(运行Form.Closing事件),最后再结束整个应用程序进程。
而且通过WPF的Window.Closing或Windows Forms的Form.Closing事件都可以取消这种形式的退出操作。
非托管的ExitProcess和TerminateProcess
这是Windows API中结束进程的非托管方法。ExitProcess结束进程更友好些,而TerminateProcess会立即强制结束进程。两者的关系有点像Environment.Exit和FailFast,但我不确定本质上是否一样。而且TerminateProcess可以指定进程返回值,但FailFast不可以。两个非托管API的执行都不回运行finally块。
使用起来很简单(关键是P/Invoke,参考:,很有用的)
using System.Runtime.InteropS
classProgram
[DllImport("kernel32.dll")]
staticexternvoid ExitProcess(uint uExitCode);
[DllImport("kernel32.dll", SetLastError =true)]
[return: MarshalAs(UnmanagedType.Bool)]
staticexternbool TerminateProcess(IntPtr hProcess, uint uExitCode);
staticvoid Main()
ExitProcess(1);
TerminateProcess(Process.GetCurrentProcess().Handle, 1);
手动发送WM_CLOSE,WM_DESTROY,WM_QUIT消息
在一个GUI程序运行环境下,我们通过得到窗体的句柄,然后便可以向该句柄发送消息,WndProc(Window Procedure)函数会处理相应的事件。其中WM_CLOSE相当于用户点击关闭按钮,使用PostMessage将WM_CLOSE发送至主窗体等价于.NET中Process类的CloseMainWindow方法,当接收到WM_CLOSE消息时,应用程序是可以选择是否真正结束程序的,如果继续结束程序而不取消。接着WM_DESTROY消息会发送,这个消息代表着窗体开始真正关闭,此时可以进行一些资源的清理。最后当前线程接收到WM_QUIT消息,线程的消息循环会被终止。
因此向窗体发送这3个消息,只有WM_CLOSE会引发Closing事件,属于正常窗体退出逻辑,其他两个中消息会直接强行关闭窗体。
注意WM_QUIT消息只能用PostMessage将其送至消息队列尾部,使用SendMessage立即发送在WPF应用程序上运行后程序没有任何反应。
下面是一个WPF程序发送下列消息,(并没有贴XAML,你一定知道怎样加3个按钮然后把Click事件和窗体的Closing事件绑在代码上吧)
using System.Collections.G
using System.L
using System.T
using System.W
using System.Windows.C
using System.Windows.D
using System.Windows.D
using System.Windows.I
using System.Windows.M
using System.Windows.Media.I
using System.Windows.N
using System.Windows.S
//外加命名空间
using System.D
using System.Runtime.InteropS
namespace Mgen.TEX
publicpartialclassMainWindow : Window
public MainWindow()
InitializeComponent();
//Windows消息值
constuint WM_CLOSE =0x10;
constuint WM_DESTROY =0x02;
constuint WM_QUIT =0x12;
//SendMessage和PostMessage的P/Invoke
[DllImport("user32.dll", CharSet =CharSet.Auto)]
staticexternIntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError =true)]
staticexternbool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
//窗体的Closing事件,判断Closing是否被运行
privatevoid Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
MessageBox.Show("Closing事件!");
//发送三种消息
privatevoid WM_CLOSE_Click(object sender, RoutedEventArgs e)
//也可以用PostMessage
SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
privatevoid WM_DESTROY_Click(object sender, RoutedEventArgs e)
//也可以用PostMessage
SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
privatevoid WM_QUIT_Click(object sender, RoutedEventArgs e)
//只能使用PostMessage去将WM_QUIT送至消息队列尾部
PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_QUIT, IntPtr.Zero, IntPtr.Zero);
阅读(...) 评论()请教一下,C#写的WinForm程序,如何才能屏蔽WM_ERASEBKGND事件?
[问题点数:30分,结帖人41417]
本版专家分:365
结帖率 86.67%
CSDN今日推荐
本版专家分:8585
本版专家分:365
本版专家分:8585
本版专家分:365
本版专家分:8585
本版专家分:365
本版专家分:3671
本版专家分:170
本版专家分:547
本版专家分:2
匿名用户不能发表回复!|
其他相关推荐C# Win32消息系列--WM
public enum WinMsg
WM_NULL = 0x0000,
WM_CREATE = 0x0001,
WM_DESTROY = 0x0002,
WM_MOVE = 0x0003,
WM_SIZE = 0x0005,
WM_ACTIVATE = 0x0006,
WM_SETFOCUS = 0x0007,
WM_KILLFOCUS = 0x0008,
WM_ENABLE = 0x000A,
WM_SETREDRAW = 0x000B,
WM_SETTEXT = 0x000C,
WM_GETTEXT = 0x000D,
WM_GETTEXTLENGTH = 0x000E,
WM_PAINT = 0x000F,
WM_CLOSE = 0x0010,
WM_QUERYENDSESSION = 0x0011,
WM_QUERYOPEN = 0x0013,
WM_ENDSESSION = 0x0016,
WM_QUIT = 0x0012,
WM_ERASEBKGND = 0x0014,
WM_SYSCOLORCHANGE = 0x0015,
WM_SHOWWINDOW = 0x0018,
WM_WININICHANGE = 0x001A,
WM_SETTINGCHANGE = 0x001A,
WM_DEVMODECHANGE = 0x001B,
WM_ACTIVATEAPP = 0x001C,
WM_FONTCHANGE = 0x001D,
WM_TIMECHANGE = 0x001E,
WM_CANCELMODE = 0x001F,
WM_SETCURSOR = 0x0020,
WM_MOUSEACTIVATE = 0x0021,
WM_CHILDACTIVATE = 0x0022,
WM_QUEUESYNC = 0x0023,
WM_GETMINMAXINFO = 0x0024,
WM_PAINTICON = 0x0026,
WM_ICONERASEBKGND = 0x0027,
WM_NEXTDLGCTL = 0x0028,
WM_SPOOLERSTATUS = 0x002A,
WM_DRAWITEM = 0x002B,
WM_MEASUREITEM = 0x002C,
WM_DELETEITEM = 0x002D,
WM_VKEYTOITEM = 0x002E,
WM_CHARTOITEM = 0x002F,
WM_SETFONT = 0x0030,
WM_GETFONT = 0x0031,
WM_SETHOTKEY = 0x0032,
WM_GETHOTKEY = 0x0033,
WM_QUERYDRAGICON = 0x0037,
WM_COMPAREITEM = 0x0039,
WM_GETOBJECT = 0x003D,
WM_COMPACTING = 0x0041,
WM_COMMNOTIFY = 0x0044,
WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047,
WM_POWER = 0x0048,
WM_COPYDATA = 0x004A,
WM_CANCELJOURNAL = 0x004B,
WM_NOTIFY = 0x004E,
WM_INPUTLANGCHANGEREQUEST = 0x0050,
WM_INPUTLANGCHANGE = 0x0051,
WM_TCARD = 0x0052,
WM_HELP = 0x0053,
WM_USERCHANGED = 0x0054,
WM_NOTIFYFORMAT = 0x0055,
WM_CONTEXTMENU = 0x007B,
WM_STYLECHANGING = 0x007C,
WM_STYLECHANGED = 0x007D,
WM_DISPLAYCHANGE = 0x007E,
WM_GETICON = 0x007F,
WM_SETICON = 0x0080,
WM_NCCREATE = 0x0081,
WM_NCDESTROY = 0x0082,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x0084,
WM_NCPAINT = 0x0085,
WM_NCACTIVATE = 0x0086,
WM_GETDLGCODE = 0x0087,
WM_SYNCPAINT = 0x0088,
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCLBUTTONDBLCLK = 0x00A3,
WM_NCRBUTTONDOWN = 0x00A4,
WM_NCRBUTTONUP = 0x00A5,
WM_NCRBUTTONDBLCLK = 0x00A6,
WM_NCMBUTTONDOWN = 0x00A7,
WM_NCMBUTTONUP = 0x00A8,
WM_NCMBUTTONDBLCLK = 0x00A9,
WM_NCXBUTTONDOWN = 0x00AB,
WM_NCXBUTTONUP = 0x00AC,
WM_NCXBUTTONDBLCLK = 0x00AD,
WM_INPUT = 0x00FF,
WM_KEYFIRST = 0x0100,
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_CHAR = 0x0102,
WM_DEADCHAR = 0x0103,
WM_SYSKEYDOWN = 0x0104,
WM_SYSKEYUP = 0x0105,
WM_SYSCHAR = 0x0106,
WM_SYSDEADCHAR = 0x0107,
WM_UNICHAR = 0x0109,
WM_KEYLAST = 0x0109,
WM_IME_STARTCOMPOSITION = 0x010D,
WM_IME_ENDCOMPOSITION = 0x010E,
WM_IME_COMPOSITION = 0x010F,
WM_IME_KEYLAST = 0x010F,
WM_INITDIALOG = 0x0110,
WM_COMMAND = 0x0111,
WM_SYSCOMMAND = 0x0112,
WM_TIMER = 0x0113,
WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x0115,
WM_INITMENU = 0x0116,
WM_INITMENUPOPUP = 0x0117,
WM_MENUSELECT = 0x011F,
WM_MENUCHAR = 0x0120,
WM_ENTERIDLE = 0x0121,
WM_MENURBUTTONUP = 0x0122,
WM_MENUDRAG = 0x0123,
WM_MENUGETOBJECT = 0x0124,
WM_UNINITMENUPOPUP = 0x0125,
WM_MENUCOMMAND = 0x0126,
WM_CHANGEUISTATE = 0x0127,
WM_UPDATEUISTATE = 0x0128,
WM_QUERYUISTATE = 0x0129,
WM_CTLCOLORMSGBOX = 0x0132,
WM_CTLCOLOREDIT = 0x0133,
WM_CTLCOLORLISTBOX = 0x0134,
WM_CTLCOLORBTN = 0x0135,
WM_CTLCOLORDLG = 0x0136,
WM_CTLCOLORSCROLLBAR = 0x0137,
WM_CTLCOLORSTATIC = 0x0138,
WM_MOUSEFIRST = 0x0200,
WM_MOUSEMOVE = 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDBLCLK = 0x0203,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_RBUTTONDBLCLK = 0x0206,
WM_MBUTTONDOWN = 0x0207,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDBLCLK = 0x0209,
WM_MOUSEWHEEL = 0x020A,
WM_XBUTTONDOWN = 0x020B,
WM_XBUTTONUP = 0x020C,
WM_XBUTTONDBLCLK = 0x020D,
WM_MOUSELAST = 0x020D,
WM_PARENTNOTIFY = 0x0210,
WM_ENTERMENULOOP = 0x0211,
WM_EXITMENULOOP = 0x0212,
WM_NEXTMENU = 0x0213,
WM_SIZING = 0x0214,
WM_CAPTURECHANGED = 0x0215,
WM_MOVING = 0x0216,
WM_POWERBROADCAST = 0x0218,
WM_DEVICECHANGE = 0x0219,
WM_MDICREATE = 0x0220,
WM_MDIDESTROY = 0x0221,
WM_MDIACTIVATE = 0x0222,
WM_MDIRESTORE = 0x0223,
WM_MDINEXT = 0x0224,
WM_MDIMAXIMIZE = 0x0225,
WM_MDITILE = 0x0226,
WM_MDICASCADE = 0x0227,
WM_MDIICONARRANGE = 0x0228,
WM_MDIGETACTIVE = 0x0229,
WM_MDISETMENU = 0x0230,
WM_ENTERSIZEMOVE = 0x0231,
WM_EXITSIZEMOVE = 0x0232,
WM_DROPFILES = 0x0233,
WM_MDIREFRESHMENU = 0x0234,
WM_IME_SETCONTEXT = 0x0281,
WM_IME_NOTIFY = 0x0282,
WM_IME_CONTROL = 0x0283,
WM_IME_COMPOSITIONFULL = 0x0284,
WM_IME_SELECT = 0x0285,
WM_IME_CHAR = 0x0286,
WM_IME_REQUEST = 0x0288,
WM_IME_KEYDOWN = 0x0290,
WM_IME_KEYUP = 0x0291,
WM_MOUSEHOVER = 0x02A1,
WM_MOUSELEAVE = 0x02A3,
WM_NCMOUSEHOVER = 0x02A0,
WM_NCMOUSELEAVE = 0x02A2,
WM_WTSSESSION_CHANGE = 0x02B1,
WM_TABLET_FIRST = 0x02c0,
WM_TABLET_LAST = 0x02df,
WM_CUT = 0x0300,
WM_COPY = 0x0301,
WM_PASTE = 0x0302,
WM_CLEAR = 0x0303,
WM_UNDO = 0x0304,
WM_RENDERFORMAT = 0x0305,
WM_RENDERALLFORMATS = 0x0306,
WM_DESTROYCLIPBOARD = 0x0307,
WM_DRAWCLIPBOARD = 0x0308,
WM_PAINTCLIPBOARD = 0x0309,
WM_VSCROLLCLIPBOARD = 0x030A,
WM_SIZECLIPBOARD = 0x030B,
WM_ASKCBFORMATNAME = 0x030C,
WM_CHANGECBCHAIN = 0x030D,
WM_HSCROLLCLIPBOARD = 0x030E,
WM_QUERYNEWPALETTE = 0x030F,
WM_PALETTEISCHANGING = 0x0310,
WM_PALETTECHANGED = 0x0311,
WM_HOTKEY = 0x0312,
WM_PRINT = 0x0317,
WM_PRINTCLIENT = 0x0318,
WM_APPCOMMAND = 0x0319,
WM_THEMECHANGED = 0x031A,
WM_HANDHELDFIRST = 0x0358,
WM_HANDHELDLAST = 0x035F,
WM_AFXFIRST = 0x0360,
WM_AFXLAST = 0x037F,
WM_PENWINFIRST = 0x0380,
WM_PENWINLAST = 0x038F,
WM_APP = 0x8000,
WM_USER = 0x0400,
没有更多推荐了,c# WM_GETTEXT怎么获得word的内容
[问题点数:40分]
本版专家分:45
结帖率 50%
CSDN今日推荐
本版专家分:219637
2013年 荣获名人称号
2012年 总版技术专家分年内排行榜第一
2013年 总版技术专家分年内排行榜第七2011年 总版技术专家分年内排行榜第五2009年 总版技术专家分年内排行榜第九
2012年11月 总版技术专家分月排行榜第一
本版专家分:45
本版专家分:45
本版专家分:45
本版专家分:16126
本版专家分:45
本版专家分:16126
本版专家分:11026
本版专家分:11026
本版专家分:45
本版专家分:11026
本版专家分:45
本版专家分:45
本版专家分:16126
匿名用户不能发表回复!|
其他相关推荐转&通过API实现C#对硬件的控制
最近在做项目的过程中,涉及到对硬件启用及禁用的功能(在指定时间段内才能启用硬件)。因为C#自身对硬件的操作基本为零,为此,搜索了一下MSDN中与设备相关的API函数。还果然就有。下面一一列举出各函数的原型及相关的说明文档。并将其转为C#代码实现。
函数一: RegisterDeviceNotification
功能:注册设备或者设备类型,在指定的窗口返回相关的信息
HDEVNOTIFY WINAPI RegisterDeviceNotification(
& __in& HANDLE hRecipient,
& __in& LPVOID
NotificationFilter,
& __in& DWORD Flags
参考说明文档:。
转为C#后的代码为:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr RegisterDeviceNotification(IntPtr
hRecipient, DEV_BROADCAST_DEVICEINTERFACE NotificationFilter,
UInt32 Flags);
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_DEVICEINTERFACE
&&&&&&&&&&&
public int dbcc_
&&&&&&&&&&&
public int dbcc_
&&&&&&&&&&&
public int dbcc_
函数二:UnregisterDeviceNotification
功能:通过名柄,关闭指定设备的信息。(主要应用于清理非托管资源,并与RegisterDeviceNotification配对使用)
BOOL WINAPI UnregisterDeviceNotification(
& __in& HDEVNOTIFY Handle
参考说明文档:。
转为C#后的代码:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint UnregisterDeviceNotification(IntPtr
函数三:SetupDiGetClassDevs
功能:获取一个指定类别或全部类别的所有已安装设备的信息。
SetupDiGetClassDevs(&&&
IN LPGUID& ClassGuid,&
OPTIONAL&&& IN
PCTSTR& Enumerator,&
OPTIONAL&&& IN
HWND& hwndParent,&
OPTIONAL&&& IN
参考说明文档:。
转为C#后的代码:
[DllImport("setupapi.dll", SetLastError = true)]
public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass,
UInt32 iEnumerator, IntPtr hParent, UInt32 nFlags);
函数四:SetupDiDestroyDeviceInfoList
功能:销毁一个设备信息集合,并且释放所有关联的内存。
WINSETUPAPI BOOL WINAPI&
SetupDiDestroyDeviceInfoList(&&&
IN HDEVINFO&
DeviceInfoSet&&&
参考说明文档:。
转为C#后的代码:
[DllImport("setupapi.dll", SetLastError = true)]
public static extern int SetupDiDestroyDeviceInfoList(IntPtr
lpInfoSet);
函数五:SetupDiEnumDeviceInfo
功能:枚举指定设备信息集合的成员,并将数据放在SP_DEVINFO_DATA中。
WINSETUPAPI BOOL WINAPI&
SetupDiEnumDeviceInfo(
IN HDEVINFO& DeviceInfoSet,
IN DWORD& MemberIndex,
&OUT PSP_DEVINFO_DATA&
DeviceInfoData&&&
参考说明文档:。
转为C#后的代码:
[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiEnumDeviceInfo(IntPtr lpInfoSet,
UInt32 dwIndex, SP_DEVINFO_DATA devInfoData);
/// &summary&
/// 设备信息数据
&/summary&
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
&&&&&&&&&&&
public int cbS
&&&&&&&&&&&
public Guid classG
&&&&&&&&&&&
public int devI
&&&&&&&&&&&
函数六:SetupDiGetDeviceRegistryProperty
功能:获取指定设备的属性。
WINSETUPAPI BOOL WINAPI&
SetupDiGetDeviceRegistryProperty(
IN HDEVINFO& DeviceInfoSet,
IN PSP_DEVINFO_DATA& DeviceInfoData,
IN DWORD& Property,
OUT PDWORD& PropertyRegDataType,
OPTIONAL&&& OUT
PBYTE& PropertyBuffer,
IN DWORD& PropertyBufferSize,
OUT PDWORD& RequiredSize&
OPTIONAL&&&
参考说明文档:。
转为C#后的代码:
[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);
函数七:SetupDiSetClassInstallParams
功能:停用设备。
WINSETUPAPI BOOL WINAPI
&SetupDiSetClassInstallParams(
HDEVINFO& DeviceInfoSet,
PSP_DEVINFO_DATA& DeviceInfoData,
OPTIONAL&&& IN
PSP_CLASSINSTALL_HEADER& ClassInstallParams,
OPTIONAL&&& IN
ClassInstallParamsSize&&&
参考说明文档:。
转为C#后的代码:
[DllImport("setupapi.dll", SetLastError = true, CharSet =
CharSet.Auto)]
public static extern bool SetupDiSetClassInstallParams(IntPtr
DeviceInfoSet, IntPtr DeviceInfoData, IntPtr ClassInstallParams,
int ClassInstallParamsSize);
函数八:SetupDiCallClassInstaller
功能:启用设备。
WINSETUPAPI BOOL WINAPI
& SetupDiCallClassInstaller(
DI_FUNCTION& InstallFunction,
HDEVINFO& DeviceInfoSet,
PSP_DEVINFO_DATA& DeviceInfoData&
OPTIONAL&&&
参考说明文档:。
转为C#后的代码:
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
public static extern Boolean SetupDiCallClassInstaller(UInt32
InstallFunction, IntPtr DeviceInfoSet, IntPtr DeviceInfoData);
通过上一篇“通过API实现C#对硬件的控制(一)”
我们掌握了我们所需要的相关API知识点。为此,我们现在来构建我们自己的外部调用类:Externs。由于有上一篇的详细说明,该处不再一一说明相关的函数知识点。
下面是该类的代码:
using System.Collections.G
using System.T
using System.Runtime.InteropS
namespace Hardware
下列所需函数可参考MSDN中与驱动程序相关的API函数
&/summary&
&&& public class
public const int DIGCF_ALLCLASSES = (0x);
public const int DIGCF_PRESENT = (0x);
public const int INVALID_HANDLE_VALUE = -1;
public const int SPDRP_DEVICEDESC = (0x);
public const int MAX_DEV_LEN = 1000;
public const int DEVICE_NOTIFY_WINDOW_HANDLE = (0x);
public const int DEVICE_NOTIFY_SERVICE_HANDLE = (0x);
public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES =
public const int DBT_DEVTYP_DEVICEINTERFACE = (0x);
public const int DBT_DEVNODES_CHANGED = (0x0007);
public const int WM_DEVICECHANGE = (0x0219);
public const int DIF_PROPERTYCHANGE = (0x);
public const int DICS_FLAG_GLOBAL = (0x);
public const int DICS_FLAG_CONFIGSPECIFIC = (0x);
public const int DICS_ENABLE = (0x);
public const int DICS_DISABLE = (0x);
/// &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
/// &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_
&&&&&&&&&&&
public int dbch_
&&&&&&&&&&&
public int dbch_
&&&&&&&&&&&
public IntPtr dbch_
&&&&&&&&&&&
public IntPtr dbch_
&&&&&&&&&&&
public Guid dbch_
&&&&&&&&&&&
public long dbch_
&&&&&&&&&&&
public byte dbch_
&&&&&&&&&&&
public byte dbch_data1;
// WM_DEVICECHANGE message
[StructLayout(LayoutKind.Sequential)]
public class DEV_BROADCAST_DEVICEINTERFACE
&&&&&&&&&&&
public int dbcc_
&&&&&&&&&&&
public int dbcc_
&&&&&&&&&&&
public int dbcc_
/// &summary&
/// 设备信息数据
/// &/summary&
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
&&&&&&&&&&&
public int cbS
&&&&&&&&&&&
public Guid classG
&&&&&&&&&&&
public int devI
&&&&&&&&&&&
/// &summary&
/// 属性变更参数
/// &/summary&
[StructLayout(LayoutKind.Sequential)]
public class SP_PROPCHANGE_PARAMS
&&&&&&&&&&&
public SP_CLASSINSTALL_HEADER ClassInstallHeader = new
SP_CLASSINSTALL_HEADER();
&&&&&&&&&&&
public int StateC
&&&&&&&&&&&
public int S
&&&&&&&&&&&
public int HwP
/// &summary&
/// 设备安装
/// &/summary&
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINSTALL_PARAMS
&&&&&&&&&&&
public int cbS
&&&&&&&&&&&
public int F
&&&&&&&&&&&
public int FlagsEx;
&&&&&&&&&&&
public IntPtr hwndP
&&&&&&&&&&&
public IntPtr InstallMsgH
&&&&&&&&&&&
public IntPtr InstallMsgHandlerContext;
&&&&&&&&&&&
public IntPtr FileQ
&&&&&&&&&&&
public IntPtr ClassInstallR
&&&&&&&&&&&
public int R
&&&&&&&&&&&
[MarshalAs(UnmanagedType.LPTStr)]
&&&&&&&&&&&
public string DriverP
[StructLayout(LayoutKind.Sequential)]
public class SP_CLASSINSTALL_HEADER
&&&&&&&&&&&
public int cbS
&&&&&&&&&&&
public int InstallF
在完成了该类后,我们还需要写一个对硬件操作与获取的操作类HardwareClass。
下面为它的完整代码:
using System.Collections.G
using System.T
using System.Runtime.InteropS
namespace Hardware
&&& public class
HardwareClass
属性#region 属性
/// &summary&
/// 返回所有硬件信息列表
/// &/summary&
&returns&&/returns&
public string[] List
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
List&string& HWList = new
List&string&();
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
Guid myGUID = System.Guid.E
&&&&&&&&&&&&&&&&&&&
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 DeviceInfoD
&&&&&&&&&&&&&&&&&&&
DeviceInfoData = new Externs.SP_DEVINFO_DATA();
&&&&&&&&&&&&&&&&&&&
DeviceInfoData.cbSize = 28;
&&&&&&&&&&&&&&&&&&&
DeviceInfoData.devInst = 0;
&&&&&&&&&&&&&&&&&&&
DeviceInfoData.classGuid = System.Guid.E
&&&&&&&&&&&&&&&&&&&
DeviceInfoData.reserved = 0;
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
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))
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
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)
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
Externs.UnregisterDeviceNotification(callback);
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
/// &summary&
/// 设置指定设备的状态
/// &/summary&
/// &param
name="match"&设备名称&/param&
/// &param
name="bEnable"&是否启用&/param&
&returns&&/returns&
public bool SetState(string[] match, bool bEnable)
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
Guid myGUID = System.Guid.E
&&&&&&&&&&&&&&&
IntPtr hDevInfo = Externs.SetupDiGetClassDevs(ref myGUID, 0,
IntPtr.Zero, Externs.DIGCF_ALLCLASSES |
Externs.DIGCF_PRESENT);
&&&&&&&&&&&&&&&
if (hDevInfo.ToInt32() == Externs.INVALID_HANDLE_VALUE)
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
Externs.SP_DEVINFO_DATA DeviceInfoD
&&&&&&&&&&&&&&&
DeviceInfoData = new Externs.SP_DEVINFO_DATA();
&&&&&&&&&&&&&&&
DeviceInfoData.cbSize = 28;
&&&&&&&&&&&&&&&
DeviceInfoData.devInst = 0;
&&&&&&&&&&&&&&&
DeviceInfoData.classGuid = System.Guid.E
&&&&&&&&&&&&&&&
DeviceInfoData.reserved = 0;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
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 =
&&&&&&&&&&&&&&&&&&&
foreach (string search in match)
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
(!DeviceName.ToString().ToLower().Contains(search.ToLower()))
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
if (bMatch)
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
OpenClose(hDevInfo, DeviceInfoData, bEnable);
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
Externs.SetupDiDestroyDeviceInfoList(hDevInfo);
&&&&&&&&&&&
&&&&&&&&&&&
catch (Exception ex)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
throw new Exception("枚举设备信息出错!", ex);
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
/// &summary&
/// 允许一个窗口或者服务接收所有硬件的通知
/// 注:目前还没有找到一个比较好的方法来处理如果通知服务。
/// &/summary&
/// &param
name="callback"&&/param&
/// &param
name="UseWindowHandle"&&/param&
&returns&&/returns&
public bool AllowNotifications(IntPtr callback, bool
UseWindowHandle)
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
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);
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
Externs.RegisterDeviceNotification(callback, dbdi,
Externs.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES |
Externs.DEVICE_NOTIFY_SERVICE_HANDLE);
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
catch (Exception ex)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
string err = ex.M
&&&&&&&&&&&&&&&
&&&&&&&&&&&
#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)
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
IntPtr ptrToP
&&&&&&&&&&&&&&&
int szDevInfoD
&&&&&&&&&&&&&&&
IntPtr ptrToDevInfoD
&&&&&&&&&&&&&&&
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,
&&&&&&&&&&&&&&&&&&&
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;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
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,
&&&&&&&&&&&&&&&
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("不能更改设备状态。");
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
catch (Exception ex)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
#endregion
有了前两篇后,我们在这里面建立一个测试项目。简单的设备管理器:)
界面如下图:
<img ALT="C#MINI设备管理器界面" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" real_src ="http://p.blog.csdn.net/images/p_blog_csdn_net/cocosoft/devman.jpg"
TITLE="转&通过API实现C#对硬件的控制" />
源码项目下载地址:。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 实现中 的文章

 

随机推荐