본문 바로가기
VB.net

InitiateSystemShutdown

by 호야호잇 2021. 4. 28.

선언:

C#

[DllImport("advapi32")]
public static extern Int32 InitiateSystemShutdown(String lpMachineName, String lpMessage, Int32 dwTimeout, Boolean bForceAppsClosed, Boolean bRebootAfterShutdown);

 

VB.NET

<DllImport("advapi32")> _
Public Shared Function InitiateSystemShutdown(lpMachineName As [String], lpMessage As [String], dwTimeout As Int32, bForceAppsClosed As [Boolean], bRebootAfterShutdown As [Boolean]) As Int32
End Function

 

 

 

사용 예제:

C#

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ApiReference {
    class ApiExample {
        
        [DllImport("advapi32")]
        public static extern Int32 InitiateSystemShutdown(String lpMachineName, String lpMessage, Int32 dwTimeout, Boolean bForceAppsClosed, Boolean bRebootAfterShutdown);

        public static void Main(string[] args) {
            Console.Write("표시할 메세지를 입력하세요: ");
        EnterMessage:
            String message = Console.ReadLine().Trim();
            if ( String.IsNullOrEmpty(message) ) {
                Console.WriteLine("다시 입력하세요");
                goto EnterMessage;
            }
            
            Console.Write("종료하기까지의 대기 시간을 입력하세요: ");
            Int32 duration;
        EnterDuration:
            try {
                duration = Int32.Parse(Console.ReadLine().Trim());
            } catch {
                Console.WriteLine("다시 입력하세요");
                goto EnterDuration;
            }
            
            // bForceAppsClosed 값이 true이면, 프로그램을 강제로 종료합니다.
            // 이 경우, 작업 데이터의 손실이 일어날 수 있습니다.
            // false일 경우엔 프로그램의 닫기 작업을 실행합니다.
            
            // 시스템 종료 관련 API를 사용하기 위해선 SeShutdownPrivilege 특권이 활성화 되어 있어야 합니다.
            // 그렇기 때문에 특권을 활성화 시켜줍니다.
            SetPrivilege("SeShutdownPrivilege"2);
            
            // bRebootAfterShutdown 은 말 그대로 true일 경우 재부팅, false일 경우 시스템 종료입니다.
            if ( InitiateSystemShutdown(Environment.MachineName, message, duration, falsefalse) == 0 )
                Console.WriteLine("InitiateSystemShutdown 실패!");
            else
                Console.WriteLine("시스템 종료합니다!");
                
            Console.ReadKey(true);
        }
        
        private static void SetPrivilege(String privilegeName, Int32 state) {
            Assembly asm = Assembly.GetAssembly(typeof(System.Diagnostics.Process));
            if ( asm == null ) return;
            
            Type t = asm.GetType("System.Diagnostics.Process");
            if ( t == null ) return;
        
            MethodInfo mi = t.GetMethod("SetPrivilege", BindingFlags.Static | BindingFlags.NonPublic);
            if ( mi == null ) return;
            
            Object[] parameters = {privilegeName, state};
            mi.Invoke(null, parameters);
        }
    }
}

 

VB.NET

Imports System
Imports System.Diagnostics
Imports System.Reflection
Imports System.Runtime.InteropServices

Namespace ApiReference
    Class ApiExample

        <DllImport("advapi32")> _
        Public Shared Function InitiateSystemShutdown(lpMachineName As [String], lpMessage As [String], dwTimeout As Int32, bForceAppsClosed As [Boolean], bRebootAfterShutdown As [Boolean]) As Int32
        End Function

        Public Shared Sub Main(args As String())
            Console.Write("표시할 메세지를 입력하세요: ")
            EnterMessage:
            Dim message As [String] = Console.ReadLine().Trim()
            If [String].IsNullOrEmpty(message) Then
                Console.WriteLine("다시 입력하세요")
                GoTo EnterMessage
            End If

            Console.Write("종료하기까지의 대기 시간을 입력하세요: ")
            Dim duration As Int32
            EnterDuration:
            Try
                duration = Int32.Parse(Console.ReadLine().Trim())
            Catch
                Console.WriteLine("다시 입력하세요")
                GoTo EnterDuration
            End Try

            ' bForceAppsClosed 값이 true이면, 프로그램을 강제로 종료합니다.
            ' 이 경우, 작업 데이터의 손실이 일어날 수 있습니다.
            ' false일 경우엔 프로그램의 닫기 작업을 실행합니다.

            ' 시스템 종료 관련 API를 사용하기 위해선 SeShutdownPrivilege 특권이 활성화 되어 있어야 합니다.
            ' 그렇기 때문에 특권을 활성화 시켜줍니다.
            SetPrivilege("SeShutdownPrivilege", 2)

            ' bRebootAfterShutdown 은 말 그대로 true일 경우 재부팅, false일 경우 시스템 종료입니다.
            If InitiateSystemShutdown(Environment.MachineName, message, duration, FalseFalse) = 0 Then
                Console.WriteLine("InitiateSystemShutdown 실패!")
            Else
                Console.WriteLine("시스템 종료합니다!")
            End If

            Console.ReadKey(True)
        End Sub

        Private Shared Sub SetPrivilege(privilegeName As [String], state As Int32)
            Dim asm As Assembly = Assembly.GetAssembly(GetType(System.Diagnostics.Process))
            If asm Is Nothing Then
                Return
            End If

            Dim t As Type = asm.[GetType]("System.Diagnostics.Process")
            If t Is Nothing Then
                Return
            End If

            Dim mi As MethodInfo = t.GetMethod("SetPrivilege", BindingFlags.[StaticOr BindingFlags.NonPublic)
            If mi Is Nothing Then
                Return
            End If

            Dim parameters As [Object]() = {privilegeName, state}
            mi.Invoke(Nothing, parameters)
        End Sub
    End Class
End Namespace

 

 

 

예제 실행 결과:\

 

 

 

매개 변수 설명:

lpMachineName - 시스템을 종료할 기계의 이름을 입력합니다.

lpMessage - 표시할 메세지를 입력합니다.

dwTimeout - 시스템을 종료하기까지 대기할 시간을 입력합니다.

bForceAppClosed - 시스템 종료 시 강제로 프로그램을 종료할 것인지의 여부를 입력합니다.

bRebootAfterShutdown - 시스템 종료 후 재부팅할 것인지의 여부를 입력합니다.

 

 

 

API 설명:

시스템을 종료합니다.

 

 

 

참고:

InitiateSystemShutdown (MSDN)

 

 

 

비고:

시스템을 종료하기 위해서는 SE_SHUTDOWN_PRIVILEGE 특권이 필요합니다. 그렇기 때문에 SetPrivilege 메서드를 이용하여 시스템 종료 특권을 활성화한 후에 InitiateSystemShutdown API를 호출하였습니다. ExitWindow, ExitWindowEx API 등도 동일하게 특권이 활성화 되어 있어야 성공적인 호출이 가능합니다.



출처: https://slaner.tistory.com/61 [꿈꾸는 프로그래머]