none
vb2005能实现锁定状态下的重启吗?有没有相关的类? RRS feed

  • 问题

  •  

    在网上找过好多资料,都是调用API实现的,但是好像都无法做到在锁定状态下的重启,不知道.net有没有相关的类可以实现?

     

    代码太长,我单独开个帖子提交

     

     

    这个代码也是只能在非锁定状态下实现各个功能,一旦锁屏,重启功能就失效了,请高人指点一下改怎么改?或者.net本身已经有相关类可以实现了?

    锁定状态是指 win+L 组合键之后的状态.

     

    2008年11月21日 10:05

答案

全部回复

  • Code Snippet

    Imports System

    Imports System.Text

    Imports System.Diagnostics

    Imports System.Runtime.InteropServices

    Public Class ExitWindwos

        Public Enum RestartOptions

            LogOff = 0

            PowerOff = 8

            Reboot = 2

            ShutDown = 1

            Suspend = -1

            Hibernate = -2

            'EWX_FORCE = 4

        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

        Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr

        Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As IntPtr) As Integer

        Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr

        Private Declare Function SetSuspendState Lib "Powrprof" (ByVal Hibernate As Integer, ByVal ForceCritical As Integer, ByVal DisableWakeEvent As Integer) As Integer

        Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As IntPtr) As Integer

        Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer

        Private 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

        Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Integer, ByVal dwReserved As Integer) As Integer

        Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Integer, ByVal lpSource As IntPtr, ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, ByVal Arguments As Integer) As Integer

     

        Private Sub ExitWindows(ByVal how As RestartOptions, ByVal force As Boolean)

            Select 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

     

        Private 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.GetLastWin32Error()))

        End Sub

     

    --待续
    2008年11月21日 10:06
  • --接上

    Code Snippet

        Private 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

     

        Private 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

     

        Private 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

     

        Private 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

     

        Public Sub LogOff() '注销

            ExitWindows(RestartOptions.Reboot, False)

        End Sub

        Public Sub PowerOff() '关闭电源

            ExitWindows(RestartOptions.PowerOff, False)

        End Sub

     

        Public Sub Reboot() '重启计算机

            ExitWindows(RestartOptions.Reboot, False)

        End Sub

        Public Sub ShutDown() '关闭系统

            ExitWindows(RestartOptions.ShutDown, False)

        End Sub

        Public Sub Suspend() '待机

            ExitWindows(RestartOptions.Suspend, False)

        End Sub

        Public Sub Hibernate() '休眠

            ExitWindows(RestartOptions.Hibernate, False)

        End Sub

     

    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

     

     

    2008年11月21日 10:07
  •  

    其实不用api  你可以用 shell execute  一个exe文件的命令

     

    "shutdown -r"

    具体参数可以设置  几秒后  什么方式  是否可以取消

    2008年11月21日 10:08
  • 好像shutdown在锁定状态下也不行的,并且,我用的服务器是windows2000的系统,没有shutdown.exe

     

    2008年11月21日 10:30
  • 可以拷贝一个shutdown.exe在你的项目里面,通过参数调用。
    2008年11月21日 15:53
    版主
  •   回楼上,shutdown.exe本身在锁定状态下也没法重启,所以此路不通.我网上搜索了一下,好像只有一个收费软件叫阿达关机的可以在锁定状态下定时重启/关机,其他的调用API的方式要么编译没通过,要么只能在非锁定状态下功能才正常,一旦锁定就不行了......

      还请高人指点了.

    2008年11月22日 6:24
  • 这就很奇怪 我用shutdown 远程重新启动别的计算机都成功过  ---没有用户登陆的状态

     

    试验下做成在 system权限下的service 也许就好用了

     

    2008年11月24日 3:05
  • 我刚才测试了一下,发现shutdown确实可以了,我以前测试过确实不行的啊,可能是某个补丁修补过了,不过我还是对编程调用API来自己实现这个功能感兴趣.所以希望有知道的不吝赐教啊~~~~~~~

     

    2008年11月24日 3:23
  • http://www.builder.com.cn/2008/0514/860789.shtml

     

    可以看看这个   shutdown之所以可以启动远程机器  是因为wmi 可以被active directory访问

     

    这个地址是一个vbs +com的例子 可以当成你程序的一部分 也可以注册成 wsc 的类com

     

    你也把它翻译成面向 .net   system.directoryService命名空间下的版本 

    2008年11月24日 4:31
  • 谢谢楼上的,WMI方式我以前用vbs脚本测试过,也是锁定状态下不行.我今天编译成exe再测试一下看看.

     

    2008年11月24日 5:06