c#.net

c# The computer power down, rebooting and logoff

우유빛 2009. 7. 16. 09:52

using System.Runtime.InteropServices;

 

// The ExitWindowsEx application programming interface (API)

// function allows a message to be sent to all executing processes for the current user,

// requesting that they terminate to allow the computer to be shut down,

// restarted or in preparation for the current user to be logged off.

// The function is available in Windows 2000 and later operating systems.

[DllImport("user32.dll", SetLastError = true)]

static extern int ExitWindowsEx(uint uFlags, uint dwReason);

 

enum ExitFlags

{

    Logoff = 0,

    Shutdown = 1,

    Reboot = 2,

    Force = 4,

    PowerOff = 8,

    ForceIfHung = 16

}

enum Reason : uint

{

    ApplicationIssue = 0x00040000,

    HardwareIssue = 0x00010000,

    SoftwareIssue = 0x00030000,

    PlannedShutdown = 0x80000000

}

 

// Elevating Privileges

// All programs execute with a set of privileges that enable and disable Windows functionality.

// For security purposes, the privileges provided to a program should be the minimum necessary to ensure correct execution.

const int PrivilegeEnabled = 0x00000002;

const int TokenQuery = 0x00000008;

const int AdjustPrivileges = 0x00000020;

const string ShutdownPrivilege = "SeShutdownPrivilege";

 

[StructLayout(LayoutKind.Sequential, Pack = 1)]

internal struct TokenPrivileges

{

    public int PrivilegeCount;

    public long Luid;

    public int Attributes;

}

 

// This function gets a handle that represents the current process.

// The handle is used to identify the process when elevating the privileges.

[DllImport("kernel32.dll")]

internal static extern IntPtr GetCurrentProcess();

 

// This function retrieves the access token for a process.

// When used with the current process handle,

// the access token holds the privilege information for the executing program.

[DllImport("advapi32.dll", SetLastError = true)]

internal static extern int OpenProcessToken(

    IntPtr processHandle,

    int desiredAccess,

    ref IntPtr tokenHandle);

 

// This function is used to perform a lookup of the locally unique identifier (LUID) for a named privilege.

// This allows the LUID for the shutdown privilege to be found in readiness for elevating the privileges of the process.

[DllImport("advapi32.dll", SetLastError = true)]

internal static extern int LookupPrivilegeValue(

    string systemName, string name, ref long luid);

 

//  Once the process handle, access token and privilege LUID are identified,

// this function is used to change the program's privileges and assign the shut down rights.

[DllImport("advapi32.dll", SetLastError = true)]

internal static extern int AdjustTokenPrivileges(

    IntPtr tokenHandle, bool disableAllPrivileges,

    ref TokenPrivileges newState,

    int bufferLength,

    IntPtr previousState,

    IntPtr length);

 

//  This method uses the four API functions in turn to identify the current process,

// retrieve the current privileges, identify the shutdown privilege and grant it to the user.

private void ElevatePrivileges()

{

    IntPtr currentProcess = GetCurrentProcess();

    IntPtr tokenHandle = IntPtr.Zero;

 

    int result = OpenProcessToken(

        currentProcess,

        AdjustPrivileges | TokenQuery,

        ref tokenHandle);

 

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

 

    TokenPrivileges tokenPrivileges;

    tokenPrivileges.PrivilegeCount = 1;

    tokenPrivileges.Luid = 0;

    tokenPrivileges.Attributes = PrivilegeEnabled;

 

    result = LookupPrivilegeValue(

        null,

        ShutdownPrivilege,

        ref tokenPrivileges.Luid);

 

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

 

    result = AdjustTokenPrivileges(

        tokenHandle,

        false,

        ref tokenPrivileges,

        0, IntPtr.Zero,

        IntPtr.Zero);

 

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

}

 

private void Shutdown(bool Force)

{

    ElevatePrivileges();

    int result = 0;

    if (Force)

    {

        // Forcing a Shutdown

        result = ExitWindowsEx(

            (uint)(ExitFlags.Shutdown | ExitFlags.PowerOff | ExitFlags.Force),

            (uint)(Reason.HardwareIssue | Reason.PlannedShutdown));

    }

    else

    {

        result = ExitWindowsEx(

            (uint)(ExitFlags.Shutdown | ExitFlags.PowerOff),

            (uint)(Reason.HardwareIssue | Reason.PlannedShutdown));

    }

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

}

 

private void Restart()

{

    ElevatePrivileges();

 

    int result = ExitWindowsEx(

        (uint)(ExitFlags.Reboot),

        (uint)(Reason.SoftwareIssue | Reason.PlannedShutdown));

 

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

}

 

private void Logoff()

{

    ElevatePrivileges();

 

    int result = ExitWindowsEx(

        (uint)(ExitFlags.Logoff),

        (uint)(Reason.ApplicationIssue | Reason.PlannedShutdown));

 

    if (result == 0)

        throw new Win32Exception(Marshal.GetLastWin32Error());

}