1、是不是用一个TIMER控制时间,然后执行关机函数就行啊?
2、执行关机函数代码时需要判别是什么系统,再选择关机函数吗?
3、关机前有程序在运行会有影响吗?
XP/2000的关机函数可以在98/ME下使用吗?

解决方案 »

  1.   

    没有通用的,nt和98的调用不一样,98下用的在nt下关不了结束进程的代码
    Option Explicit
    Const MAX_PATH& = 260Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
    Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
    Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
    Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
    Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As Long) As Long
    Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPrivate Type LUID
       lowpart As Long
       highpart As Long
    End TypePrivate Type TOKEN_PRIVILEGES
        PrivilegeCount As Long
        LuidUDT As LUID
        Attributes As Long
    End TypeConst TOKEN_ADJUST_PRIVILEGES = &H20
    Const TOKEN_QUERY = &H8
    Const SE_PRIVILEGE_ENABLED = &H2
    Const PROCESS_ALL_ACCESS = &H1F0FFFPrivate Declare Function GetVersion Lib "kernel32" () 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 Any, ReturnLength As Any) As LongType PROCESSENTRY32
      dwSize As Long
      cntUsage As Long
      th32ProcessID As Long
      th32DefaultHeapID As Long
      th32ModuleID As Long
      cntThreads As Long
      th32ParentProcessID As Long
      pcPriClassBase As Long
      dwFlags As Long
      szexeFile As String * MAX_PATH
    End Type
    '---------------------------------------
    Public Function KillApp(myName As String) As Boolean
       Const TH32CS_SNAPPROCESS As Long = 2&
       Const PROCESS_ALL_ACCESS = 0
       Dim uProcess As PROCESSENTRY32
       Dim rProcessFound As Long
       Dim hSnapshot As Long
       Dim szExename As String
       Dim exitCode As Long
       Dim myProcess As Long
       Dim AppKill As Boolean
       Dim appCount As Integer
       Dim i As Integer
       On Local Error GoTo Finish
       appCount = 0
       
       uProcess.dwSize = Len(uProcess)
       hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
       rProcessFound = ProcessFirst(hSnapshot, uProcess)
       Do While rProcessFound
           i = InStr(1, uProcess.szexeFile, Chr(0))
           szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
           If Right$(szExename, Len(myName)) = LCase$(myName) Then
               KillApp = True
               appCount = appCount + 1
               myProcess = OpenProcess(PROCESS_ALL_ACCESS, False, uProcess.th32ProcessID)
                If KillProcess(uProcess.th32ProcessID, 0) Then
                   MsgBox "Instance no. " & appCount & " of " & szExename & " was terminated!"
                End If       End If
           rProcessFound = ProcessNext(hSnapshot, uProcess)
       Loop
       Call CloseHandle(hSnapshot)
       Exit Function
    Finish:
        MsgBox "Error!"
    End Function'Terminate any application and return an exit code to Windows.
    Function KillProcess(ByVal hProcessID As Long, Optional ByVal exitCode As Long) As Boolean
        Dim hToken As Long
        Dim hProcess As Long
        Dim tp As TOKEN_PRIVILEGES
            If GetVersion() >= 0 Then        If OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) = 0 Then
                GoTo CleanUp
            End If        If LookupPrivilegeValue("", "SeDebugPrivilege", tp.LuidUDT) = 0 Then
                GoTo CleanUp
            End If        tp.PrivilegeCount = 1
            tp.Attributes = SE_PRIVILEGE_ENABLED        If AdjustTokenPrivileges(hToken, False, tp, 0, ByVal 0&, ByVal 0&) = 0 Then
                GoTo CleanUp
            End If
        End If    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, hProcessID)
        If hProcess Then        KillProcess = (TerminateProcess(hProcess, exitCode) <> 0)
            ' close the process handle
            CloseHandle hProcess
        End If
        
        If GetVersion() >= 0 Then
            ' under NT restore original privileges
            tp.Attributes = 0
            AdjustTokenPrivileges hToken, False, tp, 0, ByVal 0&, ByVal 0&
            
    CleanUp:
            If hToken Then CloseHandle hToken
        End If
        
    End Function'窗体代码
    Option Explicit'Example on how to use the code' this is the click event of a button named cmdKill
    Private Sub Command1_Click()
        ' Usage:
        Dim pID As Long
        Dim i As Integer
        Dim strExe As String
        strExe = "Notepad.Exe"
        For i = 0 To 4
            pID = Shell(strExe, vbNormalFocus)
        Next i
        'Five instances of notpade.exe is now created
        Debug.Assert False
        MsgBox "It is " & _
            KillApp(strExe) & _
            " that all instances of " & vbCrLf & _
            strExe & _
            " have been terminated!"
    End Sub
      

  2.   

    强制关机的代码:
    Option Explicit
         Public Const EWX_LogOff As Long = 0
         Public Const EWX_SHUTDOWN As Long = 1
         Public Const EWX_REBOOT As Long = 2
         Public Const EWX_FORCE As Long = 4
         Public Const EWX_POWEROFF As Long = 8
         
         'ExitWindowsEx函数可以退出登录、关机或者重新启动系统
         Public Declare Function ExitWindowsEx Lib "user32" _
         (ByVal dwOptions As Long, _
         ByVal dwReserved As Long) As Long
         
         'GetLastError函数返回本线程的最后一次错误代码。错误代码是按照线程
         '储存的,多线程也不会覆盖其他线程的错误代码。
         Public Declare Function GetLastError Lib "kernel32" () As Long
         
         Public Const mlngWindows95 = 0
         Public Const mlngWindowsNT = 1
         
         Public glngWhichWindows32 As Long
         
         ' GetVersion返回操作系统的版本。
         Public Declare Function GetVersion Lib "kernel32" () As Long
         
         Public Type LUID
         UsedPart As Long
         IgnoredForNowHigh32BitPart As Long
         End Type
         
         Public Type LUID_AND_ATTRIBUTES
         TheLuid As LUID
         Attributes As Long
         End Type
         
         Public Type TOKEN_PRIVILEGES
         PrivilegeCount As Long
         TheLuid As LUID
         Attributes As Long
         End Type
         
         'GetCurrentProcess函数返回当前进程的一个句柄。
         Public Declare Function GetCurrentProcess Lib "kernel32" () As Long
         
         'OpenProcessToken函数打开一个进程的访问代号。
         Public Declare Function OpenProcessToken Lib "advapi32" _
         (ByVal ProcessHandle As Long, _
         ByVal DesiredAccess As Long, _
         TokenHandle As Long) As Long
         
         'LookupPrivilegeValue函数获得本地唯一的标示符(LUID),用于在特定的系统中
         '表示特定的优先权。
         Public Declare Function LookupPrivilegeValue Lib "advapi32" _
         Alias "LookupPrivilegeValueA" _
         (ByVal lpSystemName As String, _
         ByVal lpName As String, _
         lpLuid As LUID) As Long
         
         'AdjustTokenPrivileges函数使能或者禁用指定访问记号的优先权。
         '使能或者禁用优先权需要TOKEN_ADJUST_PRIVILEGES访问权限。
         Public 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
         
         Public Declare Sub SetLastError Lib "kernel32" _
         (ByVal dwErrCode As Long)
         
         Public 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
      

  3.   

    '关机及重启####################################Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long Const EWX_LOGOFF = 0 '退出(注销)
     Const EWX_SHUTDOWN = 1 '关机
     Const EWX_REBOOT = 2 '重启动
     Const EWX_POWEROFF = 8 '物理关闭电源
     Const EWX_FORCE = 4 '强制关机,即不通知现在活动应用程序让其先自我关闭 Const TOKEN_ADJUST_PRIVILEGES = &H20
     Const TOKEN_QUERY = &H8
     Const SE_PRIVILEGE_ENABLED = &H2
     Const ANYSIZE_ARRAY = 1
    Type LUID
        lowpart As Long
        highpart As Long
    End TypeType LUID_AND_ATTRIBUTES
        pLuid As LUID
        Attributes As Long
    End TypeType TOKEN_PRIVILEGES
        PrivilegeCount As Long
        Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
    End TypePrivate Declare Function GetCurrentProcess Lib "kernel32" () 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 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 OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
    '关机及重启####################################Sub cyReBoot()
        AdjustTokenPrivilegesForNT
        ExitWindowsEx EWX_REBOOT, 0
    End SubSub cyShutDown()
        AdjustTokenPrivilegesForNT
        
        '在95/98中调用没作用,取得关机句柄
        If GetVersion = 90505220 Then ' NT
            ExitWindowsEx EWX_SHUTDOWN, 0
        Else
            ExitWindowsEx EWX_SHUTDOWN + EWX_POWEROFF, 0
        End If
        '如果只用 "ExitWindowsEx EWX_SHUTDOWN , 0",则不会物理关机而只会出现“您可以安全关机”之类的提示,呵呵!
    End Sub