VB.NET中實現"關機/休眠/重啟/登出"的類 (轉)

worldblog發表於2007-12-14
VB.NET中實現"關機/休眠/重啟/登出"的類 (轉)[@more@]

Imports System
Imports System.Text
Imports System.Diagnostics
Imports System.Runtime.InteropServices

  Public Class Controller
  Public Enum RestartOptions
  LogOff = 0
  PowerOff = 8
  Reboot = 2
  ShutDown = 1
  Suspend = -1
  = -2
  End Enum

  Public Structure LUID
  Dim LowPart As Integer
  Dim HighPart As Integer
  End Structure

  Public Structure LUID_AND_ATTRIBUTES

  Dim pLuid As LUID

  Dim Attributes As Integer
  End Structure


  Public Structure TOKEN_PRIVILEGES

  Dim PrivilegeCount As Integer

  Dim Privileges As LUID_AND_ATTRIBUTES
  End Structure

  Private Const TOKEN_ADJUST_PRIVILEGES = &H20
  Private Const TOKEN_QUERY = &H8
  Private Const SE_PRIVILEGE_ENABLED = &H2
  Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
  Private Const EWX_FORCE = 4
  Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr
  Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As IntPtr) As Integer
  Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr
  Declare Function SetSuspendState Lib "Powrprof" (ByVal Hibernate As Integer, ByVal ForceCritical As Integer, ByVal DisableWakeEvent As Integer) As Integer
  Declare Function OpenProcessToken Lib "adv32.dll" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As IntPtr) As Integer
  Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer
  Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As IntPtr, ByVal DisableAllPrivileges As Integer, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Integer) As Integer
  Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer
  Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Integer, ByVal lp As IntPtr, ByVal dwMessageId As Integer, ByVal dguageId As Integer, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByVal Arguments As Integer) As Integer

  Public Sub ExitWindows(ByVal how As RestartOptions, ByVal force As Boolean)
  Case how
  Case RestartOptions.Suspend
  SuspendSystem(False, force)
  Case RestartOptions.Hibernate
  SuspendSystem(True, force)
  Case Else
  ExitWindows(Convert.ToInt32(how), force)
  End Select
  End Sub

  Protected Sub ExitWindows(ByVal how As Integer, ByVal force As Boolean)
  EnableToken("SeShutdownPrivilege")
  If force Then how = how Or EWX_FORCE
  If (ExitWindowsEx(how, 0) = 0) Then Throw New PrivilegeException(FormatError(Marshal.GetLastError()))
  End Sub

  Protected Sub EnableToken(ByVal privilege As String)
  If Not CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges") Then Return
  Dim tokenHandle As IntPtr = IntPtr.Zero
  Dim privilegeLUID = New LUID()
  Dim newPrivileges = New TOKEN_PRIVILEGES()
  Dim tokenPrivileges As TOKEN_PRIVILEGES
  If (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, tokenHandle)) = 0 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
  If (LookupPrivilegeValue("", privilege, privilegeLUID)) = 0 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
  tokenPrivileges.PrivilegeCount = 1
  tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED
  tokenPrivileges.Privileges.pLuid = privilegeLUID
  Dim Size As Integer = 4
  If (AdjustTokenPrivileges(tokenHandle, 0, tokenPrivileges, 4 + (12 * tokenPrivileges.PrivilegeCount), newPrivileges, Size)) = 0 Then Throw New PrivilegeException(FormatError(Marshal.GetLastWin32Error()))
  End Sub

  Protected Sub SuspendSystem(ByVal hibernate As Boolean, ByVal force As Boolean)
  If Not CheckEntryPoint("powrprof.dll", "SetSuspendState") Then Throw New PlatformNotSupportedException("The SetSuspendState method is not supported on this system!")
  SetSuspendState(Convert.ToInt32(IIf(hibernate, 1, 0)), Convert.ToInt32(IIf(force, 1, 0)), 0)
  End Sub

  Protected Function CheckEntryPoint(ByVal library As String, ByVal method As String) As Boolean
  Dim libPtr As IntPtr = LoadLibrary(library)
  If Not libPtr.Equals(IntPtr.Zero) Then
  If Not GetProcAddress(libPtr, method).Equals(IntPtr.Zero) Then
  FreeLibrary(libPtr)
  Return True
  End If
  FreeLibrary(libPtr)
  End If
  Return False
  End Function

  Protected Function FormatError(ByVal number As Integer) As String
  Dim Buffer = New StringBuilder(255)
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, number, 0, Buffer, Buffer.Capacity, 0)
  Return Buffer.ToString()
  End Function
  End Class

  Public Class PrivilegeException
  Inherits Exception

  Public Sub New()
  MyBase.New()
  End Sub

  Public Sub New(ByVal message As String)
  MyBase.New(message)
  End Sub
  End Class

例如實現登出功能:
  Dim shutdown As New Windowntroller()
  shutdown.ExitWindows(shutdown.RestartOptions.LogOff, False)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993499/,如需轉載,請註明出處,否則將追究法律責任。

相關文章