王朝网络
分享
 
 
 

强制一个本地或远程NT系统关闭

王朝厨房·作者佚名  2007-01-04
宽屏版  字体: |||超大  

在Windows NT下,你能强制本地或远程机器定时关闭。这段代码将告诉你怎么做。你能指定系统关闭前的等待时间(0代表立即关闭),关闭进程的优先级(决定是否允许保存未完成的工作)和机器是否要重新启动。

开始一个新的Project,加入一个module,然后加入一下代码:

’判断系统是否为NT:

Private Type OSVERSIONINFO

dwOSVersionInfoSize As Long

dwMajorVersion As Long

dwMinorVersion As Long

dwBuildNumber As Long

dwPlatformId As Long

szCSDVersion As String * 128 ’ Maintenance string for PSS usage

End Type

Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long

Private Const VER_PLATFORM_WIN32_NT = 2

Private Const VER_PLATFORM_WIN32_WINDOWS = 1

Private Const VER_PLATFORM_WIN32s = 0

’报告API错误:

Private Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100

Private Const FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000

Private Const FORMAT_MESSAGE_FROM_HMODULE = &H800

Private Const FORMAT_MESSAGE_FROM_STRING = &H400

Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000

Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200

Private Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF

Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long

’ =====================================================================

’ NT Only

Private Type LARGE_INTEGER

LowPart As Long

HighPart As Long

End Type

Private Type LUID

LowPart As Long

HighPart As Long

End Type

Private Type LUID_AND_ATTRIBUTES

pLuid As LUID

Attributes As Long

End Type

Private Type TOKEN_PRIVILEGES

PrivilegeCount As Long

Privileges(0 To 0) As LUID_AND_ATTRIBUTES

End Type

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

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

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Declare Function GetTokenInformation Lib "advapi32.dll" (ByVal TokenHandle As Long, TokenInformationClass As Integer, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) As Long

Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (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 Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long

Private Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"

Private Const SE_PRIVILEGE_ENABLED = &H2

Private Const READ_CONTROL = &H20000

Private Const STANDARD_RIGHTS_ALL = &H1F0000

Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)

Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)

Private Const STANDARD_RIGHTS_REQUIRED = &HF0000

Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)

Private Const TOKEN_ASSIGN_PRIMARY = &H1

Private Const TOKEN_DUPLICATE = (&H2)

Private Const TOKEN_IMPERSONATE = (&H4)

Private Const TOKEN_QUERY = (&H8)

Private Const TOKEN_QUERY_SOURCE = (&H10)

Private Const TOKEN_ADJUST_PRIVILEGES = (&H20)

Private Const TOKEN_ADJUST_GROUPS = (&H40)

Private Const TOKEN_ADJUST_DEFAULT = (&H80)

Private Const TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _

TOKEN_ASSIGN_PRIMARY Or _

TOKEN_DUPLICATE Or _

TOKEN_IMPERSONATE Or _

TOKEN_QUERY Or _

TOKEN_QUERY_SOURCE Or _

TOKEN_ADJUST_PRIVILEGES Or _

TOKEN_ADJUST_GROUPS Or _

TOKEN_ADJUST_DEFAULT)

Private Const TOKEN_READ = (STANDARD_RIGHTS_READ Or TOKEN_QUERY)

Private Const TOKEN_WRITE = (STANDARD_RIGHTS_WRITE Or _

TOKEN_ADJUST_PRIVILEGES Or _

TOKEN_ADJUST_GROUPS Or _

TOKEN_ADJUST_DEFAULT)

Private Const TOKEN_EXECUTE = (STANDARD_RIGHTS_EXECUTE)

Private Const TokenDefaultDacl = 6

Private Const TokenGroups = 2

Private Const TokenImpersonationLevel = 9

Private Const TokenOwner = 4

Private Const TokenPrimaryGroup = 5

Private Const TokenPrivileges = 3

Private Const TokenSource = 7

Private Const TokenStatistics = 10

Private Const TokenType = 8

Private Const TokenUser = 1

Private Declare Function InitiateSystemShutdown Lib "advapi32.dll" Alias "InitiateSystemShutdownA" (ByVal lpMachineName As String, ByVal lpMessage As String, ByVal dwTimeout As Long, ByVal bForceAppsClosed As Long, ByVal bRebootAfterShutdown As Long) As Long

Private Declare Function AbortSystemShutdown Lib "advapi32.dll" Alias "AbortSystemShutdownA" (ByVal lpMachineName As String) As Long

’ ================================================================

Public Function WinError(ByVal lLastDLLError As Long) As String

Dim sBuff As String

Dim lCount As Long

’返回与LastDLLError关联的错误消息:

sBuff = String$(256, 0)

lCount = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, _

0, lLastDLLError, 0&, sBuff, Len(sBuff), ByVal 0)

If lCount Then

WinError = Left$(sBuff, lCount)

End If

End Function

Public Function IsNT() As Boolean

Static bOnce As Boolean

Static bValue As Boolean

’返回系统是否为NT:

If Not (bOnce) Then

Dim tVI As OSVERSIONINFO

tVI.dwOSVersionInfoSize = Len(tVI)

If (GetVersionEx(tVI) <> 0) Then

bValue = (tVI.dwPlatformId = VER_PLATFORM_WIN32_NT)

bOnce = True

End If

End If

IsNT = bValue

End Function

Private Function NTEnableShutDown(ByRef sMsg As String) As Boolean

Dim tLUID As LUID

Dim hProcess As Long

Dim hToken As Long

Dim tTP As TOKEN_PRIVILEGES, tTPOld As TOKEN_PRIVILEGES

Dim lTpOld As Long

Dim lR As Long

’在NT下,我们必须给试图关闭系统的进程SE_SHUTDOWN_NAME特权

’否则,所有企图关闭系统的调用都会无效!

’寻找Shoudown特权令牌的LUID:

lR = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, tLUID)

’如果我们找到了

If (lR <> 0) Then

’取得当前进程的句柄:

hProcess = GetCurrentProcess()

If (hProcess <> 0) Then

’打开令牌来Adjust和Query(用户可能没有权限)

lR = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken)

If (lR <> 0) Then

’好,我们现在可以调整Shutdown特权了:

With tTP

.PrivilegeCount = 1

With .Privileges(0)

.Attributes = SE_PRIVILEGE_ENABLED

.pLuid.HighPart = tLUID.HighPart

.pLuid.LowPart = tLUID.LowPart

End With

End With

’现在允许这个进程关闭系统:

lR = AdjustTokenPrivileges(hToken, 0, tTP, Len(tTP), tTPOld, lTpOld)

If (lR <> 0) Then

NTEnableShutDown = True

Else

Err.Raise eeSSDErrorBase + 6, App.EXEName & ".mShutDown", "不能shutdown:你没有关闭本系统的权限。[" & WinError(Err.LastDllError) & "]"

End If

’记得用完后关闭这个句柄:

CloseHandle hToken

Else

Err.Raise eeSSDErrorBase + 6, App.EXEName & ".mShutDown", "不能shutdown:你没有关闭本系统的权限。[" & WinError(Err.LastDllError) & "]"

End If

Else

Err.Raise eeSSDErrorBase + 5, App.EXEName & ".mShutDown", "不能shutdown:不能终止当前进程。[" & WinError(Err.LastDllError) & "]"

End If

Else

Err.Raise eeSSDErrorBase + 4, App.EXEName & ".mShutDown", "不能shutdown:找不到SE_SHUTDOWN_NAME特权值。[" & WinError(Err.LastDllError) & "]"

End If

End Function

Public Function NTForceTimedShutdown( _

Optional ByVal lTimeOut As Long = -1, _

Optional ByVal sMsg As String = "", _

Optional ByVal sMachineNetworkName As String = vbNullString, _

Optional ByVal bForceAppsToClose As Boolean = False, _

Optional ByVal bReboot As Boolean = False _

) As Boolean

Dim lR As Long

If IsNT Then

’如果我们在NT下,确信我们已经给了这个进程关闭系统的特权:

If Not (NTEnableShutDown(sMsg)) Then

Exit Function

End If

’这是定时关闭系统的代码:

lR = InitiateSystemShutdown(sMachineNetworkName, sMsg, lTimeOut, bForceAppsToClose, bReboot)

If (lR = 0) Then

Err.Raise eeSSDErrorBase + 2, App.EXEName & ".mShutDown", "InitiateSystemShutdown failed: " & WinError(Err.LastDllError)

End If

Else

Err.Raise eeSSDErrorBase + 1, App.EXEName & ".mShutDown", "函数仅在Windows NT下有效。"

End If

End Function

Public Function NTAbortTimedShutdown(Optional ByVal sMachineNetworkName As String = vbNullString)

AbortSystemShutdown sMachineNetworkName

End Function

为了试验一次shutdown,在窗体上放两个Command按钮和一个Text,然后粘贴一下代码。注意,你必须在运行前保存你的工作,因为Shutdown也将关闭VB且不会给你任何有关保存的询问!

点击Command1,它根据Text里的值开始一次定时关机。要终止Shutdown,点Command2。

Private Sub Command1_Click()

If (MsgBox("你确定要强制定时关机吗?", vbYesNo Or vbQuestion) = vbYes) Then

NTForceTimedShutdown CLng(Text1.Text), "系统将在" & Text1.Text & "秒后关闭..."

End If

End Sub

Private Sub Command2_Click()

NTAbortTimedShutdown

End Sub

Private Sub Form_Load()

Text1.Text = 60

End Sub

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有