/// <summary> /// Выполняет выход из сеанса пользователя, зевершение работы системы или её перезагрузку /// </summary> /// <param name="procHandle">Дескриптор приложения выполняющего вызов данного метода</param> /// <param name="shutdownFlag">Вариант завершения работы</param> public static void ExitWindows(IntPtr procHandle, uint shutdownFlag) { IntPtr tokenHandle = IntPtr.Zero; try { if (!Win32ApiHelper.OpenProcessToken(procHandle, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, out tokenHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Не удалось открыть дескриптор токена процесса"); } Win32ApiHelper.TOKEN_PRIVILEGES tokenPrivs = new Win32ApiHelper.TOKEN_PRIVILEGES(); tokenPrivs.PrivilegeCount = 1; tokenPrivs.Privileges = new Win32ApiHelper.LUID_AND_ATTRIBUTES[1]; tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!Win32ApiHelper.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out tokenPrivs.Privileges[0].Luid)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Не удалось преобразовать имя привилегии выключения"); } if (!Win32ApiHelper.AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivs, 0, IntPtr.Zero, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Не удалось настроить права токена процесса"); } if (!Win32ApiHelper.ExitWindowsEx(shutdownFlag, (uint)Win32ApiHelper.ShutdownReasonCodes.SHTDN_REASON_MAJOR_APPLICATION | (uint)Win32ApiHelper.ShutdownReasonCodes.SHTDN_REASON_MINOR_INSTALLATION | (uint)Win32ApiHelper.ShutdownReasonCodes.SHTDN_REASON_FLAG_PLANNED)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Ошибка при выключении системы"); } } finally { if (tokenHandle != IntPtr.Zero) { Win32ApiHelper.CloseHandle(tokenHandle); } } }