Выключение компьютера под управлением Windows (C++).

Следующий код демонстрирует процесс выключения компьютера под управлением Windows, начиная с Windows 2000 Professional.
#include <windows.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "advapi32.lib")

void SystemShutdown()
{
     HANDLE hToken;
     TOKEN_PRIVILEGES tkp;

     // Для начала получаем токен текущего процесса.
     // Все дело в том, что в Windows процесс должен обладать
     // необходимыми привилегиями, чтобы иметь возможность выключать, 
     // или ребутить систему.
     OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken));

     // Получаем LUID, для активирования необходимых нам привилегий. 
     // Ключевой параметр здесь SE_SHUTDOWN_NAME. Он отвечает за возможность процесса 
     // выключать систему. 
     LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 

     // Далее мы заполняем нашу структуру tkp необходимыми параметрами

     // количество привилегий которое мы будем изменять
     tkp.PrivilegeCount = 1; 

     // активируем нужный нам параметр 
     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

     // ф-ция говорит сама за себя. Устанавливаем активированные выше привилегии в наш процесс.
     AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

     // Собственно ф-ция выключения компьютера.
     ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, SHTDN_REASON_FLAG_PLANNED);
}

За полным списком всех параметров функции ExitWindowsEx добро пожаловать в MSDN.
Хочется обратить внимание на то, что функция ExitWindowsEx является полностью асинхронной. При удачном ее выполнении она возвратит результат отличный от нуля. Но это, на самом деле, не является индикатором того, что система действительно будет выключена. Успешное выполнение данной функции говорит лишь о том, что процесс завершения работы системы был инициирован корректно. Но вот как дальше пойдет этот процесс, в сущности неизвестно. Он может быть прерван, как самой системой, так и другим приложением. В случае неудачи функция возвратит ноль, за более точным описанием проблемы обращаться следует, как всегда, к GetLastError.

Комментарии

Популярные сообщения из этого блога

Лакедра

Бухта Спокойная