【问题标题】:How to turn off pc via windows API?如何通过 Windows API 关闭电脑?
【发布时间】:2009-10-01 13:06:16
【问题描述】:

从来没有编写过 winapi,所以我在这里遇到了一个小问题。

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

我找到了这个例子link text 然后我找到了这个例子如何更改权限link text

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

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

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

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

非常感谢大家。

【问题讨论】:

    标签: c++ windows winapi application-shutdown


    【解决方案1】:
    // ==========================================================================
    // 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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用ShellExecute() 拨打shutdown.exe

      【讨论】:

        【解决方案3】:

        这对于丹尼尔的答案的cmets来说有点多,所以我会放在这里。

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

        ExitWindowsEx 的文档包含这一行:

        要关闭或重新启动系统, 调用进程必须使用 AdjustTokenPrivileges 函数 启用SE_SHUTDOWN_NAME 权限。 如需更多信息,请参阅Running with Special Privileges

        他们也有一些example code。在紧要关头,您可以复制它。

        【讨论】:

        • 我喜欢你的示例代码,甚至让它在 gcc 下工作。知道这段代码和 Jacob 在页面下方推荐的解决方案有什么区别吗?谢谢
        • 嘿。谢谢,但为了记录,这是微软的代码,不是我的。
        • 除非没有其他好的方法,否则我不会使用 Jacob 的方法。它也可以工作,但它会创建一个完全独立的进程,然后将命令解释器加载到其中,然后执行目录搜索以找到 shutdown.exe 可执行文件,然后启动第三个进程来加载并运行它。无论如何,当您关闭时,额外的工作可能不会那么明显,但这是问题的原则......
        【解决方案4】:

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

        试试

        ExitWindowsEx(EWX_POWEROFF, 0);
        

        【讨论】:

        • 你告诉我的正是我上面写的。我得到一个错误 0x522 - 客户没有持有所需的权限。正是我最初遇到的问题以及关于该参数的问题。感谢您的帮助
        • 我喜欢这个答案,但根据文档,你不应该使用 0 作为第二个参数。除其他弊端外,它可能会在重新启动时将关闭报告为“计划外”,从而减慢速度。可能值的列表可在 msdn.microsoft.com/en-us/library/aa376885(VS.85).aspx 获得。我建议 SHTDN_REASON_MAJOR_APPLICATION。
        【解决方案5】:
        #include<iostream>
        using namespace std;
        int main(){
        system("shutdown -s -f -t 0");
        }
        

        【讨论】:

          【解决方案6】:

          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 解决方案相比,它的优势在于调用进程不需要属于活动用户。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-25
            相关资源
            最近更新 更多