Главная > Программирование > Как программно перезагрузить компьютер

Как программно перезагрузить компьютер

У вас никогда не возникало необходимости вызвать команду перезагрузки компьютера из своей программы? Иногда это бывает необходимо, например, когда для внесения тех или иных изменений в систему обязательно нужно перезагрузиться. Вы должны выдать диалоговое окно содержанием: "Для внесения изменений в систему необходимо перезагрузиться. Произвести перезагрузку сейчас? (Да, Нет)". Это диалоговое окно стандартное, и я покажу как его вызвать, кроме того, существует ещё один способ отправить компьютер на перезагрузку, правда он работает только в Win2k. Но обо всём по порядку.

Способ 1 (простой)

Для вызова стандартного диалогового окна перезагрузки существует API функция RestartDialog.

int RestartDialog(
HWND hParent,
LPCWSTR pszPrompt,
DWORD dwFlags
);

hParent - указатель на родительское окно
pszPrompt - текст сообщения которое будет выдаваться непосредственно перед стандартным сообщением "Для внесения изменений в систему необходимо перезагрузиться. Произвести перезагрузку сейчас?"
dwFlags - флаги, показывают тип диалогового окна (например: EWX_REBOOT - окно подтверждения перезагрузки, EWX_POWEROFF - окно подтверждения отключения компа и др.)

Есть одна тонкость сообщения должно быть в строке в Unicode формате, т.е. на каждый символ 2 байта. Для перевода обычной строки в Unicode есть MFC макрос CA2W. Например можно вызвать перезагрузку системы из программы на С++. Следующий код пишем на клик какой-либо кнопки:

LPCWSTR str;
CString str2;
str2.Append("Проге очень нужна перезагрузка. ");
str=CA2W(str2.GetString());
RestartDialog(this->m_hWnd,str,EWX_REBOOT);

Способ 2 (навороченный)

Способ работает только в Win2k. Здесь всё не так просто. Функция для перезагрузки:

BOOL MySystemShutdown( LPTSTR lpMsg )
{
HANDLE hToken; // указатель на идентификатор процесса
TOKEN_PRIVILEGES tkp; // указатель на идентифицирующую структуру
BOOL fResult; // флаг отключения

// получение идентификатора текущего процесса, для получения прав на отключение
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;

// Полчение LUID
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; // установка одной привелегии
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

//Установка привелегии отключения для этого процесса.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);

// Если ошибка то выход.
if (GetLastError() != ERROR_SUCCESS)
return FALSE;

// Отображение диалогового окна.
fResult = InitiateSystemShutdown(
NULL, // отключение локального компа
lpMsg, // сообщение для юзера
20, // задержка диалогового окна
FALSE, // просить/не просить юзера закрыть все окна перед перезагрузкой
TRUE); // перезагружаться/не перезагружаться после отключения
if (!fResult)
return FALSE;

// Отменить привилегии отключения.
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);
return TRUE;
}

Основная суть здесь в том что, ваша программа перед вызовом InitiateSystemShutdown, должна получить соответствующие привилегии на отключение иначе ничего не получится.

После вызова функции появится диалоговое окно, в котором будет выдано указанное сообщение. Начнётся отсчёт времени, после чего произойдёт перезагрузка. Пользователь не сможет отменить это действие и закрыть окно. Если указать время задержки 0 сек, то перезагрузка пойдёт сразу без всяких сообщений.

Если кто знает ещё способы перезагрузки или выключения компа, пишите мне.


© 2005 GMC gimix@yandex.ru
Талантов Сергей
Используются технологии uCoz