728x90
반응형
728x170
using System;
using System.Runtime.InteropServices;
/// <summary>
/// 종료 플래그 종류
/// </summary>
public enum ExitFlagType
{
/// <summary>
/// 로그오프
/// </summary>
LogOff = 0,
/// <summary>
/// 셧다운
/// </summary>
Shutdown = 1,
/// <summary>
/// 리부팅
/// </summary>
Reboot = 2,
/// <summary>
/// 강제 여부
/// </summary>
Force = 4,
/// <summary>
/// 전원 끄기
/// </summary>
PowerOff = 8,
/// <summary>
/// 보류시 강제 여부
/// </summary>
ForceIfHung = 16
}
/// <summary>
/// 사유 종류
/// </summary>
public enum ReasonType : uint
{
/// <summary>
/// 애플리케이션 이슈
/// </summary>
ApplicationIssue = 0x00040000,
/// <summary>
/// 하드웨어 이슈
/// </summary>
HardwareIssue = 0x00010000,
/// <summary>
/// 소프트웨어 이슈
/// </summary>
SoftwareIssue = 0x00030000,
/// <summary>
/// 계획 셧다운
/// </summary>
PlannedShutdown = 0x80000000
}
/// <summary>
/// 토큰 특권
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TokenPrivileges
{
/// <summary>
/// 특권 수
/// </summary>
public int PrivilegeCount;
/// <summary>
/// LUID
/// </summary>
public long LUID;
/// <summary>
/// 어트리뷰트
/// </summary>
public int Attributes;
}
#region 확장 윈도우 종료하기 - ExitWindowsEx(flagType, reasonType)
/// <summary>
/// 확장 윈도우 종료하기
/// </summary>
/// <param name="flagType">플래그 종류</param>
/// <param name="reasonType">사유 종류</param>
/// <returns>처리 결과</returns>
[DllImport("user32.dll", SetLastError = true)]
private static extern int ExitWindowsEx(uint flagType, uint reasonType);
#endregion
#region 현재 프로세스 구하기 - GetCurrentProcess();
/// <summary>
/// 현재 프로세스 구하기
/// </summary>
/// <returns>현재 프로세스 핸들</returns>
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
#endregion
#region 프로세스 토큰 열기 - OpenProcessToken(processHandle, desiredAccess, tokenHandle)
/// <summary>
/// 프로세스 토큰 열기
/// </summary>
/// <param name="processHandle">프로세스 핸들</param>
/// <param name="desiredAccess">희망 액세스</param>
/// <param name="tokenHandle">토큰 핸들</param>
/// <returns>처리 결과</returns>
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int OpenProcessToken(IntPtr processHandle, int desiredAccess, ref IntPtr tokenHandle);
#endregion
#region 특권 값 조사하기 - LookupPrivilegeValue(systemName, name, uid)
/// <summary>
/// 특권 값 조사하기
/// </summary>
/// <param name="systemName">시스템명</param>
/// <param name="name">명칭</param>
/// <param name="uid">UID</param>
/// <returns>처리 결과</returns>
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LookupPrivilegeValue(string systemName, string name, ref long uid);
#endregion
#region 토큰 특권 조정하기 - AdjustTokenPrivileges(tokenHandle, disableAllPrivileges, newState, bufferLength, previousState, length)
/// <summary>
/// 토큰 특권 조정하기
/// </summary>
/// <param name="tokenHandle">토큰 핸들</param>
/// <param name="disableAllPrivileges">모든 특권 비활성화 여부</param>
/// <param name="newState">새로운 상태</param>
/// <param name="bufferLength">버퍼 길이</param>
/// <param name="previousState">이전 상태</param>
/// <param name="length">길이</param>
/// <returns>처리 결과</returns>
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int AdjustTokenPrivileges(IntPtr tokenHandle, bool disableAllPrivileges, ref TokenPrivileges newState, int bufferLength, IntPtr previousState, IntPtr length);
#endregion
#region 특권 올리기 - ElevatePrivileges()
/// <summary>
/// 특권 올리기
/// </summary>
private void ElevatePrivileges()
{
IntPtr currentProcessHandle = GetCurrentProcess();
IntPtr tokenHandle = IntPtr.Zero;
int result = OpenProcessToken(currentProcessHandle, 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());
}
}
#endregion
#region 윈도우즈 셧다운 하기 - ShutdownWindows(force)
/// <summary>
/// 윈도우즈 셧다운 하기
/// </summary>
/// <param name="force">강제 여부</param>
public void ShutdownWindows(bool force)
{
ElevatePrivileges();
int result = 0;
if(force)
{
result = ExitWindowsEx
(
(uint)(ExitFlagType.Shutdown | ExitFlagType.PowerOff | ExitFlagType.Force),
(uint)(ReasonType.HardwareIssue | ReasonType.PlannedShutdown)
);
}
else
{
result = ExitWindowsEx
(
(uint)(ExitFlagType.Shutdown | ExitFlagType.PowerOff),
(uint)(ReasonType.HardwareIssue | ReasonType.PlannedShutdown)
);
if(result == 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
#endregion
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 숫자 문자열 여부 구하기 (0) | 2014.12.31 |
---|---|
[C#/COMMON] 운영 체제 버전 정보 구하기 (0) | 2014.12.31 |
[C#/COMMON] WindowsIdentity 클래스 : GetCurrent 정적 메소드를 사용해 현재 사용자명 구하기 (0) | 2014.12.31 |
[C#/COMMON] 윈도우즈 로그오프 하기 (0) | 2014.12.31 |
[C#/COMMON] 윈도우즈 재시작 하기 (0) | 2014.12.31 |
[C#/COMMON] ApplicationDeployment 클래스 : 쿼리 문자열 구하기 (0) | 2014.12.31 |
[C#/COMMON] Environment 클래스 : GetEnvironmentVariable 정적 메소드를 사용해 윈도우즈 디렉토리 경로 구하기 (0) | 2014.12.31 |
[C#/COMMON] 환경 변수 값 구하기 (0) | 2014.12.31 |
[C#/COMMON] Environment 클래스 : GetFolderPath 정적 메소드를 사용해 특수 디렉토리 경로 구하기 (0) | 2014.12.31 |
[C#/COMMON] 컴퓨터명 구하기 (0) | 2014.12.31 |
댓글을 달아 주세요