Как выключить компьютер через Windows API?
-
19-09-2019 - |
Вопрос
я никогда запрограммировал WinAPI, поэтому у меня возникла небольшая проблема.
Мне нужно выключить компьютер из приложения.
Я нашел этот пример текст ссылки затем я нашел этот пример, как изменить привилегии текст ссылки
Но у меня проблема с тем, как получить этот параметр HANDLE hToken // дескриптор токена доступа
Я думаю, что мне нужно сделать это в следующем порядке, чтобы получить параметр OpenProcessToken LookupprivileGevalue AdvitationTokenPivileges, но есть много параметров, которые я понятия не имею, что с ними делать.
Возможно, у вас есть пример того, как мне получить этот параметр HANDLE hToken, чтобы это работало.
Кстати, я уже видел следующий пост текст ссылки
Большое спасибо всем вам.
Решение
Это слишком много для комментариев к ответу Дэниела, поэтому я оставлю это здесь.
Похоже, ваша основная проблема на данный момент заключается в том, что ваш процесс не работает с привилегиями, необходимыми для завершения работы системы.
Документы для ВыходWindowsEx содержать эту строку:
Чтобы выключить или перезапустить систему, процесс вызова должен использовать
AdjustTokenPrivileges
функционировать, чтобы включитьSE_SHUTDOWN_NAME
привилегия.Для получения дополнительной информации см. Бег с особыми привилегиями.
У них также есть некоторые пример кода.В крайнем случае, вы можете просто скопировать это.
Другие советы
// ==========================================================================
// system shutdown
// nSDType: 0 - Shutdown the system
// 1 - Shutdown the system and turn off the power (if supported)
// 2 - Shutdown the system and then restart the system
void SystemShutdown(UINT nSDType)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp ;
::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);
::LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1 ; // set 1 privilege
tkp.Privileges[0].Attributes= SE_PRIVILEGE_ENABLED;
// get the shutdown privilege for this process
::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
switch (nSDType)
{
case 0: ::ExitWindowsEx(EWX_SHUTDOWN|EWX_FORCE, 0); break;
case 1: ::ExitWindowsEx(EWX_POWEROFF|EWX_FORCE, 0); break;
case 2: ::ExitWindowsEx(EWX_REBOOT |EWX_FORCE, 0); break;
}
}
Вы могли бы использовать ШеллExecute() звонить выключение.exe
http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx
Пытаться
ExitWindowsEx(EWX_POWEROFF, 0);
#include<iostream>
using namespace std;
int main(){
system("shutdown -s -f -t 0");
}
Некоторый рабочий код для InitiateSystemShutdownEx
:
// Get the process token
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken);
// Build a token privilege request object for shutdown
TOKEN_PRIVILEGES tk;
tk.PrivilegeCount = 1;
tk.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue(NULL, TEXT("SeShutdownPrivilege"), &tk.Privileges[0].Luid);
// Adjust privileges
AdjustTokenPrivileges(hToken, FALSE, &tk, 0, NULL, 0);
// Go ahead and shut down
InitiateSystemShutdownEx(NULL, NULL, 0, FALSE, FALSE, 0);
Насколько я могу судить, это преимущество перед ExitWindowsEx
Решение состоит в том, что вызывающий процесс не обязательно должен принадлежать активному пользователю.