当前位置:编程学习 > VB >>

vb6 中利用api 关机问题

Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Const EWX_FORCE = 4
Private Const EWX_LOGOFF = 0
Private Const EWX_REBOOT = 2
Private Const EWX_SHUTDOWN = 1
Private Sub Command1_Click()
ExitWindowsEx EWX_FORCE, 0&
End Sub
Private Sub Command2_Click()
ExitWindowsEx EWX_REBOOT, ByVal 0&
End Sub
Private Sub Form_Load()
Command1.Caption = "注销"
Command2.Caption = "重启"
Command3.Caption = "关机"
End Sub
'重启按键无反应,请问是否代码问题还是权限问题?
补充:Private Declare Function RtlAdjustPrivilege& Lib "ntdll " (ByVal Privilege&, ByVal Newvalue&, ByVal NewThread&, Oldvalue&)
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Const SE_ExitWindowsEx_PRIVILEGE& = 19 '提升权限
Private Const EWX_LOGOFF = 0 '注销
Private Const EWX_REBOOT = 2 '重启
Private Const EWX_SHUTDOWN = 1 '关机
Private Sub Command1_Click()
RtlAdjustPrivilege SE_ExitWindowsEx_PRIVILEGE, 1, 0, 0
ExitWindowsEx EWX_LOGOFF, 0 '正确代码,原因权限不够
End Sub
答案:
要先获得权限,看下面代码,注意函数 AdjustToken 
将下面内容保存为".frm"文件
------------
VERSION 5.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 2490
ClientLeft = 60
ClientTop = 345
ClientWidth = 2145
LinkTopic = "Form1"
ScaleHeight = 2490
ScaleWidth = 2145
StartUpPosition = 3 'Windows Default
Begin VB.CheckBox Check1
Caption = "强制"
Height = 315
Left = 780
TabIndex = 3
Top = 1950
Width = 795
End
Begin VB.CommandButton Command2
Caption = "重启"
Height = 465
Left = 240
TabIndex = 2
Top = 1260
Width = 1635
End
Begin VB.CommandButton Command1
Caption = "注销"
Height = 465
Left = 240
TabIndex = 1
Top = 660
Width = 1635
End
Begin VB.CommandButton cmdForceShutdown
Caption = "关机"
Height = 435
Left = 240
TabIndex = 0
Top = 90
Width = 1635
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Dim force As Boolean
Private Type LUID
UsedPart As Long
IgnoredForNowHigh32BitPart As Long
End Type

Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
TheLuid As LUID
Attributes As Long
End Type

' Beginning of Code
Private Const EWX_SHUTDOWN As Long = 1
Private Const EWX_FORCE As Long = 4
Private Const EWX_REBOOT As Long = 2
Private Const EWX_LOGOFF As Long = 0

Private Declare Function ExitWindowsEx Lib "user32" (ByVal dwOptions As Long, ByVal dwReserved As Long) As Long

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long

Private Sub AdjustToken()

Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
Dim hdlProcessHandle As Long
Dim hdlTokenHandle As Long
Dim tmpLuid As LUID
Dim tkp As TOKEN_PRIVILEGES
Dim tkpNewButIgnored As TOKEN_PRIVILEGES
Dim lBufferNeeded As Long
Dim lngRtn As Long

hdlProcessHandle = GetCurrentProcess()
'MsgBox lngRtn
lngRtn = OpenProcessToken(hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle)
'MsgBox lngRtn
' Get the LUID for shutdown privilege.
lngRtn = LookupPrivilegeValue("", "SeShutdownPrivilege", tmpLuid)
'MsgBox lngRtn
tkp.PrivilegeCount = 1 ' One privilege to set
tkp.TheLuid = tmpLuid
tkp.Attributes = SE_PRIVILEGE_ENABLED

' Enable the shutdown privilege in the access token of this
' process.
lngRtn = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded)
'MsgBox lngRtn
End Sub

Private Sub Check1_Click()
If Check1.Value = 0 Then
force = False
Else
force = True
End If
End Sub

Private Sub cmdForceShutdown_Click()
If force = True Then
ExitWindowsEx (EWX_SHUTDOWN Or EWX_FORCE), &HFFFF
Else
ExitWindowsEx (EWX_SHUTDOWN), &HFFFF
End If
End Sub

Private Sub Command1_Click()
If force = True Then
ExitWindowsEx (EWX_LOGOFF Or EWX_FORCE), &HFFFF
Else
ExitWindowsEx (EWX_LOGOFF), &HFFFF
End If
End Sub

Private Sub Command2_Click()
If force = True Then
ExitWindowsEx (EWX_REBOOT Or EWX_FORCE), &HFFFF
Else
ExitWindowsEx (EWX_REBOOT), &HFFFF
End If
End Sub

Private Sub Form_Load()
AdjustToken
End Sub
原则上,只改这一次,下一次开机会还原,但如果需重开机,才会Update Registry中的设定,并重开机。

  如果要永久设定其设定值,请将

b = ChangeDisplaySettings(DevM, 0)

  改成

b = ChangeDisplaySettings(DevM, CDS_UPDATEREGISTRY)

  注:

  DevM.dmBitsPerPel 便是设定颜色数,其实应说每个Pixel要多少Bits来显示

  4 --> 16色
  8 --> 256色
  16 --> 65536色 以此类推

Option Explicit
Private Declare Function EnumDisplaySettings Lib "user32" Alias _
"EnumDisplaySettingsA" (ByVal lpszDeviceName As Long, _
ByVal iModeNum As Long, lpDevMode As Any) As Long

Private Declare Function ChangeDisplaySettings Lib "user32" Alias _
"ChangeDisplaySettingsA" (lpDevMode As Any, ByVal dwflags As Long) As Long
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, _
ByVal dwReserved As Long) As Long

Const EWX_REBOOT = 2 ’ 重开机
Const CCDEVICENAME = 32
Const CCFORMNAME = 32

Const DM_BITSPERPEL = &H40000
Const DISP_CHANGE_SUCCESSFUL = 0
Const DISP_CHANGE_RESTART = 1
Const CDS_UPDATEREGISTRY = 1
Private Type DEVMODE
dmDeviceName As String * CCDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer

dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer

dmFormName As String * CCFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Private DevM As DEVMODE
Private Sub Command1_Click()
Dim a As Boolean
Dim i As Long
Dim b As Long
Dim ans As Long
a = EnumDisplaySettings(0, 0, DevM) ’Initial Setting
DevM.dmBitsPerPel = 8 ’设定成256色
DevM.dmFields = DM_BITSPERPEL
b = ChangeDisplaySettings(DevM, 0)
If b = DISP_CHANGE_RESTART Then
 ans = MsgBox("要重开机设定才能完成,重开?", vbOKCancel)
 If ans = 1 Then
  b = ChangeDisplaySettings(DevM, CDS_UPDATEREGISTRY)
  Call ExitWindowsEx(EWX_REBOOT, 0)
 End If
Else
 If b <> DISP_CHANGE_SUCCESSFUL Then
  Call MsgBox("设定有误", vbCritical)
 End If
End If
End Sub
不是权限的问题,你的代码好像不对哈!!
不要用这个函数private const EWX_FORCE=4
你可以直接用这个:
Shell "shutdown -r"
答案补充
在WindowsNT/2000/XP中,您无法直接通过ExitWindowsEx关闭计算机,而必须先调用AdjustTokenPrivileges   函数使得SE_SHUTDOWN_NAME的privilege为有效,请参考以下文章,他说明了如何关闭Windows   NT/2000/XP:   
PRB: ExitWindowsEx API Does Not Reboot Windows NT (Q176695)
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q176695
ExitWindowsEx 

VB声明
Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
说明
退出windows,并用特定的选项重新启动
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
uFlags Long,指定下述一个或多个标志(用OR运算符合并到一起)
EWX_FORCE 易做图中止没有响应的进程
EWX_LOGOFF 中止进程,然后注销
EWX_SHUTDOWN 关掉系统

上一个:vb如何用通用对话框打开图片文件
下一个:计算机VB考试,求助各位大虾,加急

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,