VB.NET中实现"关机/休眠/重启/注销"的类
1 Imports System
2 Imports System.Text
3 Imports System.Diagnostics
4 Imports System.Runtime.InteropServices
5 Public Class WindowsController
6 Public Enum RestartOptions
7 LogOff = 0
8 PowerOff = 8
9 Reboot = 2
10 ShutDown = 1
11 Suspend = -1
12 Hibernate = -2
13 End Enum
14 Public Structure LUID
15 Dim LowPart As Integer
16 Dim HighPart As Integer
17 End Structure
18 Public Structure LUID_AND_ATTRIBUTES
19 Dim pLuid As LUID
20 Dim Attributes As Integer
21 End Structure
22 Public Structure TOKEN_PRIVILEGES
23 Dim PrivilegeCount As Integer
24 Dim Privileges As LUID_AND_ATTRIBUTES
25 End Structure
26 Private Const TOKEN_ADJUST_PRIVILEGES = &H20
27 Private Const TOKEN_QUERY = &H8
28 Private Const SE_PRIVILEGE_ENABLED = &H2
29 Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
30 Private Const EWX_FORCE = 4
31 Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr
32 Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As IntPtr) As Integer
33 Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr
34 Declare Function SetSuspendState Lib "Powrprof" (ByVal Hibernate As Integer, ByVal ForceCritical As Integer, ByVal
35 DisableWakeEvent As Integer) As Integer
36 Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer,
37 ByRef TokenHandle As IntPtr) As Integer
38 Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String,
39 ByVal lpName As String, ByRef lpLuid As LUID) As Integer
40 Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As IntPtr, ByVal DisableAllPrivileges As
41 Integer, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef
42 ReturnLength As Integer) As Integer
43 Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer
44 Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Integer, ByVal lpSource As
45 IntPtr, ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer,
46 ByVal Arguments As Integer) As Integer
47 Public Sub ExitWindows(ByVal how As RestartOptions, ByVal force As Boolean)
48 Select Case how
49 Case RestartOptions.Suspend
50 SuspendSystem(False, force)
51 Case RestartOptions.Hibernate
52 SuspendSystem(True, force)
53 Case Else
54 ExitWindows(Convert.ToInt32(how), force)
55 End Select
56 End Sub
57 Protected Sub ExitWindows(ByVal how As Integer, ByVal force As Boolean)
58 EnableToken("SeShutdownPrivilege")
59 If force Then how = how Or EWX_FORCE
60 If (ExitWindowsEx(how, 0) = 0) Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
61 End Sub
62 Protected Sub EnableToken(ByVal privilege As String)
63 If Not CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges") Then Return
64 Dim tokenHandle As IntPtr = IntPtr.Zero
65 Dim privilegeLUID = New LUID()
66 Dim newPrivileges = New TOKEN_PRIVILEGES()
67 Dim tokenPrivileges As TOKEN_PRIVILEGES
68 If (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, tokenHandle)) = 0
69 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
70 If (LookupPrivilegeValue("", privilege, privilegeLUID)) = 0 Then Throw New PrivilegeException(FormatError
71 (Marshal.GetLastWin32Error()))
72 tokenPrivileges.PrivilegeCount = 1
73 tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED
74 tokenPrivileges.Privileges.pLuid = privilegeLUID
75 Dim Size As Integer = 4
76 If (AdjustTokenPrivileges(tokenHandle, 0, tokenPrivileges, 4 + (12 * tokenPrivileges.PrivilegeCount),
77 newPrivileges, Size)) = 0 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
78 End Sub
79 Protected Sub SuspendSystem(ByVal hibernate As Boolean, ByVal force As Boolean)
80 If Not CheckEntryPoint("powrprof.dll", "SetSuspendState") Then Throw New PlatformNotSupportedException("The
81 SetSuspendState method is not supported on this system!")
82 SetSuspendState(Convert.ToInt32(IIf(hibernate, 1, 0)), Convert.ToInt32(IIf(force, 1, 0)), 0)
83 End Sub
84 Protected Function CheckEntryPoint(ByVal library As String, ByVal method As String) As Boolean
85 Dim libPtr As IntPtr = LoadLibrary(library)
86 If Not libPtr.Equals(IntPtr.Zero) Then
87 If Not GetProcAddress(libPtr, method).Equals(IntPtr.Zero) Then
88 FreeLibrary(libPtr)
89 Return True
90 End If
91 FreeLibrary(libPtr)
92 End If
93 Return False
94 End Function
95 Protected Function FormatError(ByVal number As Integer) As String
96 Dim Buffer = New StringBuilder(255)
97 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, number, 0, Buffer, Buffer.Capacity, 0)
98 Return Buffer.ToString()
99 End Function
100 End Class
101 Public Class PrivilegeException
102 Inherits Exception
103 Public Sub New()
104 MyBase.New()
105 End Sub
106 Public Sub New(ByVal message As String)
107 MyBase.New(message)
108 End Sub
109 End Class
110 '例如实现注销功能:
111 Dim shutdown As New WindowsController()
112 shutdown.ExitWindows(shutdown.RestartOptions.LogOff, False)
113
114 '用静态的方法比较好:
115 Public shared sub WindowsShutDown(ByVal how As RestartOptions, ByVal force As Boolean)
116 Dim shutdown As New WindowsController()
117 Shutdown.ExitWindows(how, force)
118 End sub
119
2 Imports System.Text
3 Imports System.Diagnostics
4 Imports System.Runtime.InteropServices
5 Public Class WindowsController
6 Public Enum RestartOptions
7 LogOff = 0
8 PowerOff = 8
9 Reboot = 2
10 ShutDown = 1
11 Suspend = -1
12 Hibernate = -2
13 End Enum
14 Public Structure LUID
15 Dim LowPart As Integer
16 Dim HighPart As Integer
17 End Structure
18 Public Structure LUID_AND_ATTRIBUTES
19 Dim pLuid As LUID
20 Dim Attributes As Integer
21 End Structure
22 Public Structure TOKEN_PRIVILEGES
23 Dim PrivilegeCount As Integer
24 Dim Privileges As LUID_AND_ATTRIBUTES
25 End Structure
26 Private Const TOKEN_ADJUST_PRIVILEGES = &H20
27 Private Const TOKEN_QUERY = &H8
28 Private Const SE_PRIVILEGE_ENABLED = &H2
29 Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
30 Private Const EWX_FORCE = 4
31 Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr
32 Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As IntPtr) As Integer
33 Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr
34 Declare Function SetSuspendState Lib "Powrprof" (ByVal Hibernate As Integer, ByVal ForceCritical As Integer, ByVal
35 DisableWakeEvent As Integer) As Integer
36 Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer,
37 ByRef TokenHandle As IntPtr) As Integer
38 Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String,
39 ByVal lpName As String, ByRef lpLuid As LUID) As Integer
40 Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As IntPtr, ByVal DisableAllPrivileges As
41 Integer, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef
42 ReturnLength As Integer) As Integer
43 Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer
44 Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Integer, ByVal lpSource As
45 IntPtr, ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer,
46 ByVal Arguments As Integer) As Integer
47 Public Sub ExitWindows(ByVal how As RestartOptions, ByVal force As Boolean)
48 Select Case how
49 Case RestartOptions.Suspend
50 SuspendSystem(False, force)
51 Case RestartOptions.Hibernate
52 SuspendSystem(True, force)
53 Case Else
54 ExitWindows(Convert.ToInt32(how), force)
55 End Select
56 End Sub
57 Protected Sub ExitWindows(ByVal how As Integer, ByVal force As Boolean)
58 EnableToken("SeShutdownPrivilege")
59 If force Then how = how Or EWX_FORCE
60 If (ExitWindowsEx(how, 0) = 0) Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
61 End Sub
62 Protected Sub EnableToken(ByVal privilege As String)
63 If Not CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges") Then Return
64 Dim tokenHandle As IntPtr = IntPtr.Zero
65 Dim privilegeLUID = New LUID()
66 Dim newPrivileges = New TOKEN_PRIVILEGES()
67 Dim tokenPrivileges As TOKEN_PRIVILEGES
68 If (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, tokenHandle)) = 0
69 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
70 If (LookupPrivilegeValue("", privilege, privilegeLUID)) = 0 Then Throw New PrivilegeException(FormatError
71 (Marshal.GetLastWin32Error()))
72 tokenPrivileges.PrivilegeCount = 1
73 tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED
74 tokenPrivileges.Privileges.pLuid = privilegeLUID
75 Dim Size As Integer = 4
76 If (AdjustTokenPrivileges(tokenHandle, 0, tokenPrivileges, 4 + (12 * tokenPrivileges.PrivilegeCount),
77 newPrivileges, Size)) = 0 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
78 End Sub
79 Protected Sub SuspendSystem(ByVal hibernate As Boolean, ByVal force As Boolean)
80 If Not CheckEntryPoint("powrprof.dll", "SetSuspendState") Then Throw New PlatformNotSupportedException("The
81 SetSuspendState method is not supported on this system!")
82 SetSuspendState(Convert.ToInt32(IIf(hibernate, 1, 0)), Convert.ToInt32(IIf(force, 1, 0)), 0)
83 End Sub
84 Protected Function CheckEntryPoint(ByVal library As String, ByVal method As String) As Boolean
85 Dim libPtr As IntPtr = LoadLibrary(library)
86 If Not libPtr.Equals(IntPtr.Zero) Then
87 If Not GetProcAddress(libPtr, method).Equals(IntPtr.Zero) Then
88 FreeLibrary(libPtr)
89 Return True
90 End If
91 FreeLibrary(libPtr)
92 End If
93 Return False
94 End Function
95 Protected Function FormatError(ByVal number As Integer) As String
96 Dim Buffer = New StringBuilder(255)
97 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, number, 0, Buffer, Buffer.Capacity, 0)
98 Return Buffer.ToString()
99 End Function
100 End Class
101 Public Class PrivilegeException
102 Inherits Exception
103 Public Sub New()
104 MyBase.New()
105 End Sub
106 Public Sub New(ByVal message As String)
107 MyBase.New(message)
108 End Sub
109 End Class
110 '例如实现注销功能:
111 Dim shutdown As New WindowsController()
112 shutdown.ExitWindows(shutdown.RestartOptions.LogOff, False)
113
114 '用静态的方法比较好:
115 Public shared sub WindowsShutDown(ByVal how As RestartOptions, ByVal force As Boolean)
116 Dim shutdown As New WindowsController()
117 Shutdown.ExitWindows(how, force)
118 End sub
119