永发信息网

[VB]为什么使用 ExitWindowsEx 函数没办法实现关闭计算机

答案:4  悬赏:80  手机版
解决时间 2021-04-08 15:20
程序如下:
'EWX_FORCE 强迫中止没有响应的进程
'EEWX_LOGOFF 中止进程,然后注销
'EEWX_REBOOT 重新引导系统
'EEWX_SHUTDOWN 关闭系统
'EWX_POWEROFF 关闭系统电源
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long '定义ExitWi...函数
Private Sub Command1_Click()

Call ExitWindowsEx(EEWX_SHUTDOWN + EWX_POWEROFF, 0)

End Sub
我的系统是XP的.无论使用哪一个参数都是注销,不能实现重启或关机.把所有的参数加上都是注销!能帮忙实现看是怎么回事吗?
请先看清楚题目!是VB的.不是VC/DELPHI/C#...
-----
能帮忙给出调整权限的代码吗?定义API函数可以省略
最佳答案
退出操作系统可以调用Windows API的ExitWindowsEx函数。在Win9x下,只要简单地调用ExitWindowsEx函数就可以实现关机或者重新启动。但是在Win 2000/XP下调用ExitWindowsEx函数时,还需要先调用AdjustTokenPrivileges函数。下面的例子在Win9x和Win 2000/XP下都可以使用。请参考程序中的注释。
例子:
1、建立一个窗体,在上面放置4个按钮,按钮设置如下:
控件 控件名 Caption属性
---------------------------------------------------
CommandButton cmdLogoff 注销
CommandButton cmdForceLogoff 强制注销
CommandButton cmdShutdown 关机
CommandButton cmdForceShutdown 强制关机
2、将下面的代码加入窗体中:
Option Explicit
Private Const EWX_LogOff As Long = 0
Private Const EWX_SHUTDOWN As Long = 1
Private Const EWX_REBOOT As Long = 2
Private Const EWX_FORCE As Long = 4
Private Const EWX_POWEROFF As Long = 8

'ExitWindowsEx函数可以退出登录、关机或者重新启动系统
Private Declare Function ExitWindowsEx Lib "user32" _
(ByVal dwOptions As Long, _
ByVal dwReserved As Long) As Long

'GetLastError函数返回本线程的最后一次错误代码。错误代码是按照线程
'储存的,多线程也不会覆盖其他线程的错误代码。
Private Declare Function GetLastError Lib "kernel32" () As Long

Private Const mlngWindows95 = 0
Private Const mlngWindowsNT = 1

Public glngWhichWindows32 As Long

' GetVersion返回操作系统的版本。
Private Declare Function GetVersion Lib "kernel32" () As Long

Private Type LUID
UsedPart As Long
IgnoredForNowHigh32BitPart As Long
End Type

Private Type LUID_AND_ATTRIBUTES
TheLuid As LUID
Attributes As Long
End Type

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

'GetCurrentProcess函数返回当前进程的一个句柄。
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

'OpenProcessToken函数打开一个进程的访问代号。
Private Declare Function OpenProcessToken Lib "advapi32" _
(ByVal ProcessHandle As Long, _
ByVal DesiredAccess As Long, _
TokenHandle As Long) As Long

'LookupPrivilegeValue函数获得本地唯一的标示符(LUID),用于在特定的系统中
'表示特定的优先权。
Private Declare Function LookupPrivilegeValue Lib "advapi32" _
Alias "LookupPrivilegeValueA" _
(ByVal lpSystemName As String, _
ByVal lpName As String, _
lpLuid As LUID) As Long

'AdjustTokenPrivileges函数使能或者禁用指定访问记号的优先权。
'使能或者禁用优先权需要TOKEN_ADJUST_PRIVILEGES访问权限。
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 Declare Sub SetLastError Lib "kernel32" _
(ByVal dwErrCode As Long)

Private Sub AdjustToken()

'********************************************************************
'* 这个过程设置正确的优先权,以允许在Windows NT下关机或者重新启动。
'********************************************************************

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

'使用SetLastError函数设置错误代码为0。
'这样做,GetLastError函数如果没有错误会返回0
SetLastError 0

' GetCurrentProcess函数设置 hdlProcessHandle变量
hdlProcessHandle = GetCurrentProcess()

If GetLastError <> 0 Then
MsgBox "GetCurrentProcess error==" & GetLastError
End If

OpenProcessToken hdlProcessHandle, _
(TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle

If GetLastError <> 0 Then
MsgBox "OpenProcessToken error==" & GetLastError
End If

' 获得关机优先权的LUID
LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid

If GetLastError <> 0 Then
MsgBox "LookupPrivilegeValue error==" & GetLastError
End If

tkp.PrivilegeCount = 1 ' 设置一个优先权
tkp.TheLuid = tmpLuid
tkp.Attributes = SE_PRIVILEGE_ENABLED

' 对当前进程使能关机优先权
AdjustTokenPrivileges hdlTokenHandle, _
False, _
tkp, _
Len(tkpNewButIgnored), _
tkpNewButIgnored, _
lBufferNeeded

If GetLastError <> 0 Then
MsgBox "AdjustTokenPrivileges error==" & GetLastError
End If

End Sub

Private Sub cmdLogoff_Click()

ExitWindowsEx (EWX_LogOff), &HFFFF
MsgBox "ExitWindowsEx's GetLastError " & GetLastError

End Sub

Private Sub cmdForceLogoff_Click()

ExitWindowsEx (EWX_LogOff Or EWX_FORCE), &HFFFF
MsgBox "调用ExitWindowsEx函数后的GetLastError " & GetLastError

End Sub

Private Sub cmdShutdown_Click()

If glngWhichWindows32 = mlngWindowsNT Then
AdjustToken
MsgBox "调用AdjustToken后的GetLastError " & GetLastError
End If

ExitWindowsEx (EWX_SHUTDOWN), &HFFFF
MsgBox "调用ExitWindowsEx函数后的GetLastError " & GetLastError

End Sub

Private Sub cmdForceShutdown_Click()
If glngWhichWindows32 = mlngWindowsNT Then
AdjustToken
MsgBox "调用AdjustToken后的GetLastError " & GetLastError
End If

ExitWindowsEx (EWX_SHUTDOWN Or EWX_FORCE), &HFFFF
MsgBox "ExitWindowsEx's GetLastError " & GetLastError

End Sub

Private Sub Form_Load()
'********************************************************************
'* 当项目启动时,调用GetVersion检查操作系统。
'********************************************************************
Dim lngVersion As Long

lngVersion = GetVersion()

If ((lngVersion And &H80000000) = 0) Then
glngWhichWindows32 = mlngWindowsNT
MsgBox "在Windows NT或Windows 2000下运行"
Else
glngWhichWindows32 = mlngWindows95
MsgBox "在Windows 95/98/Me下运行"
End If

End Sub
全部回答
你是98的代码,举人是2000/xp的代码.
NT以上的操作系统还要调整程序的权限,使你的程序具有ShutDown的权限,所以还需要几个API: OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges
你好! NT以上的操作系统还要调整程序的权限,使你的程序具有ShutDown的权限,所以还需要几个API: OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges 我的回答你还满意吗~~
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
阿里餐厅怎么去啊,有知道地址的么
野花骚民间小调黑毛唱的
单选题美国最大银行花旗银行集团2008年1月15
怎么找到win10自带的浏览器
单选题鞍钢的建设,考虑的主要区位因素是A.原
形容天空蓝心情好句子,赞美拉萨天空的句子
温州乐园的门票包括哪些游戏项目,哪些项目是
二元一次方程{6x-5y=3 6x+y=-15 x怎么解
宾川县医药公司城北门市部怎么去啊,有知道地
下列各句中,标点符号使用全都正确的一项是A.
金刚菩提冰冻会裂不
欧凯罗酒店地址在哪,我要去那里办事
人人直播一直在回放准备中是什么原因
如图所示,某兴趣小组同学在进行酸碱中和反应
别上头是什么意思,过年三十什么时间给观音菩
推荐资讯
英雄联盟怎么查不到匹配局数?这是怎么到达30
佰仟金融工作怎么样,深圳佰仟金融公司待遇怎
广州纳仕人力资源有限公司怎么去啊,有知道地
海尔微波炉保修卡是什么样子的?
我是郫县人,现在在外地,这个月社保未扣,卡
单选题下列句子中的“乎”的用法判断正确的一
姚明成为了NBA一流中锋,给中国人争得了荣誉
邯郸附近的城市,哪些旅游景点?两天能回来的
舒欣早餐在哪里啊,我有事要去这个地方
电高压锅怎么蒸米饭,用美的电压力锅蒸米饭应
麦当劳永华道餐厅地址在哪,我要去那里办事
云南大理过桥米线(商务学院分店)这个地址在什
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?