如何通过Windows API关闭电脑?

发布于 2024-08-06 13:02:28 字数 677 浏览 4 评论 0原文

从未编写过winapi,所以我在这里遇到了一些问题。

我需要从我的应用程序中关闭我的电脑。

我找到了这个示例 链接文本 然后我找到这个示例如何更改权限链接文本

但我有如何获取该参数的问题 HANDLE hToken // 访问令牌句柄

我认为我需要按照下一个顺序来获取参数 OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges 但有很多参数我不知道如何处理它们。

也许你有一些例子,我如何获取 HANDLE hToken 参数来使其工作。

顺便说一句,我已经看到以下帖子链接文本

非常感谢大家。

I never programmed a winapi so i have a little problem here .

I need turn off my pc from my application .

I found this example link text then i found this example how to change privileges link text

But i have problem how to get that parameter HANDLE hToken // access token handle

I think i need to make it in the next order to get the parameter
OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges
but there are a lot parameters that i have no idea what to do with them .

maybe you have jere some example how i get that HANDLE hToken parameter to make that work .

By the way I already saw the following post link text

Thanks a lot all you .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

人│生佛魔见 2024-08-13 13:02:28
// ==========================================================================
// 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;
    }
}
// ==========================================================================
// 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;
    }
}
愛上了 2024-08-13 13:02:28

您可以使用 ShellExecute() 来调用 shutdown.exe

You could use ShellExecute() to call shutdown.exe

想你的星星会说话 2024-08-13 13:02:28

对于Daniel的回答的评论有点多,所以我就放在这里。

目前看来您的主要问题是您的进程没有以执行系统关闭所需的权限运行。

ExitWindowsEx 的文档包含以下行:

要关闭或重新启动系统,
调用进程必须使用
AdjustTokenPrivileges 函数
启用 SE_SHUTDOWN_NAME 权限。
有关详细信息,请参阅运行
特殊特权

他们还有一些示例代码。在紧要关头,你可以复制它。

This is a bit much for the comments on Daniel's answer, so I'll put it here.

It looks like your main issue at this point is that your process isn't running with the priveleges required to perform a system shutdown.

The docs for ExitWindowsEx contain this line:

To shut down or restart the system,
the calling process must use the
AdjustTokenPrivileges function to
enable the SE_SHUTDOWN_NAME privilege.
For more information, see Running with
Special Privileges
.

They also have some example code. In a pinch, you can just copy that.

太傻旳人生 2024-08-13 13:02:28
#include<iostream>
using namespace std;
int main(){
system("shutdown -s -f -t 0");
}
#include<iostream>
using namespace std;
int main(){
system("shutdown -s -f -t 0");
}
瀟灑尐姊 2024-08-13 13:02:28

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 解决方案的优点是调用进程不需要属于活动用户。

Some working code for 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);

So far as I can tell, the advantage to this over the ExitWindowsEx solution is that the calling process does not need to belong to the active user.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文