C++ 如何通过windows API关闭电脑?
我从来没有编写过winapi,所以这里有一个小问题 我需要从我的应用程序关闭我的电脑 我找到了这个示例,然后我找到了这个示例如何更改特权 但我有问题如何获取参数句柄hToken//access令牌句柄 我想我需要在下一个步骤中得到参数 OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges 但是有很多参数,我不知道如何处理它们 也许你有一些例子,我是如何得到HANDLE-hToken参数,使其工作的 顺便说一下,我已经看到了下面的帖子 非常感谢各位。您可以打电话给 试一试C++ 如何通过windows API关闭电脑?,c++,windows,winapi,application-shutdown,C++,Windows,Winapi,Application Shutdown,我从来没有编写过winapi,所以这里有一个小问题 我需要从我的应用程序关闭我的电脑 我找到了这个示例,然后我找到了这个示例如何更改特权 但我有问题如何获取参数句柄hToken//access令牌句柄 我想我需要在下一个步骤中得到参数 OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges 但是有很多参数,我不知道如何处理它们 也许你有一些例子,我是如何得到HANDLE-hToken参数,使其工作的 顺便说一下,我已经看到了下面的帖
这是对丹尼尔答案的一点评论,所以我将把它放在这里 看起来您目前的主要问题是,您的进程没有使用执行系统关闭所需的权限运行 的单据包含此行: 要关闭或重新启动系统, 调用进程必须使用
AdjustTokenPrivileges
功能
启用SE\u SHUTDOWN\u NAME
权限。
有关详细信息,请参阅
他们也有一些。在紧要关头,你可以复制它。\include
// ==========================================================================
// 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;
}
}
使用名称空间std;
int main(){
系统(“关闭-s-f-t 0”);
}
初始化SystemShutdownex的一些工作代码:
// 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
解决方案相比,此解决方案的优势在于调用过程不需要属于活动用户。您准确地告诉了我上面所写的内容。我得到一个错误0x522-客户端没有持有所需的特权。这正是我一开始遇到的问题,以及我关于这个参数的问题。谢谢你的帮助我喜欢这个答案,但是根据文档,你不应该用0作为第二个参数。在其他的问题中,它可能会在重新启动时报告关机是“非计划的”,从而减慢速度。有关可能值的列表,请访问。我建议使用SHTDN\u REASON\u MAJOR\u应用程序。我喜欢您的示例代码,甚至可以在gcc下工作。你知道这段代码和Jacob推荐的解决方案有什么不同吗?谢谢。谢谢,但请记住这是微软的代码,不是我的。除非没有其他好方法,否则我不会使用雅各布的方法。它可能也可以工作,但它会创建一个完整的单独进程,然后将命令interprer加载到其中,然后外出并进行目录搜索以查找shutdown.exe可执行文件,然后启动第三个进程以加载并运行该文件。不管怎样,当你关机时,额外的工作可能不会那么明显,但这是问题的基本原理。。。
#include<iostream>
using namespace std;
int main(){
system("shutdown -s -f -t 0");
}
// 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);