2009-10-01 44 views
3

从来没有编程一个winapi所以我有一个小问题在这里。如何通过Windows API关闭电脑?

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

我发现这个例子link text后来我发现这个例子如何更改权限link text

但我有问题,如何获取参数HANDLE hToken //访问令牌手柄

我想我需要使它在下一个命令获取参数 OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges 但有很多参数,我不知道如何处理它们。

也许你有jere一些例子我如何得到HANDLE hToken参数来完成这项工作。

顺便说一句,我已经看到了下面的帖子link text

非常感谢你。

回答

3

这是一个有点吃不消了对丹尼尔的回答意见,所以我把它放在这里。

看起来你现在的主要问题是你的进程没有在执行系统关闭所需的条件下运行。

ExitWindowsEx的文档包含此行:

关闭或重新启动系统, 调用进程必须使用 AdjustTokenPrivileges功能 启用SE_SHUTDOWN_NAME特权。 有关更多信息,请参见Running with Special Privileges

他们也有一些example code。在一个捏,你可以复制它。

+0

我喜欢你的示例代码,甚至使它在gcc下工作。 任何想法这个代码和雅各布推荐页面的解决方案有什么不同? 谢谢 – 2009-10-01 15:18:19

+0

Heh。谢谢,但记录它是微软的代码,而不是我的。 – 2009-10-01 18:44:15

+0

除非没有其他好的方法,否则我不会使用雅各布的方法。它也可以工作,但它会创建一个完整的独立进程,然后加载一个命令解释器,然后出去执行目录搜索以找到shutdown.exe可执行文件,然后启动第三个进程来加载并运行它。无论如何,当你关闭时,额外的工作可能不会那么明显,但这是问题的原理...... – 2009-10-01 18:45:24

4

http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx

尝试

ExitWindowsEx(EWX_POWEROFF, 0); 
+0

你告诉我我上面写的是什么。 而我得到一个错误0x522 - 所需的特权不是由客户端持有。 准确地说,我在第一个地方的问题和我关于该参数的问题。 感谢您的帮助 – 2009-10-01 13:48:56

+1

我喜欢这个答案,但根据文档,您不应该使用0作为第二个参数。除其他弊端外,它可能会在关机时将关机报告为“未计划”,从而导致速度下降。可以从http://msdn.microsoft.com/en-us/library/aa376885(VS.85).aspx获取可能的值列表。我建议SHTDN_REASON_MAJOR_APPLICATION。 – 2009-10-01 13:55:24

7
// ========================================================================== 
// 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; 
    } 
} 
+0

好 - 尽管缺少很多错误检查:) – paulm 2013-05-07 11:58:05

0
#include<iostream> 
using namespace std; 
int main(){ 
system("shutdown -s -f -t 0"); 
} 
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解决方案是调用进程并不需要属于活跃用户。

相关问题