空腹おやじのログと備忘録

VBA(主にExcel)でいろいろな実験的な事とか、Linuxのコマンドとか設定とかについて忘れないように、あれこれと・・・

【C++】Windowsをシャットダウン or サスペンド させる

スタートメニューを辿っていくのが面倒だったので、
実行ファイルを作って、デスクトップにショートカットを作ることにしました。

環境
Windows 10 Home 64bit
Visual Studio Community 2019

#include <Windows.h>
#include <iostream>

using namespace std;


BOOL EnablePrivileges(LPCTSTR lpcPrivilegeName, BOOL bEnable);

int main()
{
    int iResult{ 1 };
    wstring sResult;

    while (true)
    {
        //SE_SHUTDOWN_NAME(シャットダウン特権) を有効にする
        if (!EnablePrivileges(SE_SHUTDOWN_NAME, TRUE))
        {
            sResult = L"EnablePrivileges failed";

            break;
        }

        if (!InitiateSystemShutdownEx(nullptr, nullptr, 0, FALSE, FALSE, SHTDN_REASON_FLAG_USER_DEFINED))
        {
            sResult = L"InitiateSystemShutdownEx failed";

            break;
        }

        sResult = L"InitiateSystemShutdownEx succeeded !";

        iResult = 0;

        break;
    }

    wcout << sResult << endl;

    return iResult;
}

BOOL EnablePrivileges(LPCTSTR lpcPrivilegeName, BOOL isEnable)
{
    //プロセストークン取得
    HANDLE hToken;
    BOOL isSuccess = OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
        &hToken);

    if (!isSuccess)
    {
        return FALSE;
    }

    //特権に対応するLUID取得
    LUID luid;
    isSuccess = LookupPrivilegeValue(nullptr, lpcPrivilegeName, &luid);
    if (isSuccess)
    {
        //TOKEN_PRIVILEGES型のオブジェクトに、LUIDと特権の属性(有効にするか無効にするか)を指定
        TOKEN_PRIVILEGES tokenPrivileges;
        tokenPrivileges.PrivilegeCount = 1;
        tokenPrivileges.Privileges[0].Luid = luid;
        tokenPrivileges.Privileges[0].Attributes = isEnable ? SE_PRIVILEGE_ENABLED : 0;

        //特権を設定する
        isSuccess = AdjustTokenPrivileges(hToken,
            FALSE,
            &tokenPrivileges, 0, 0, 0);
    }

    CloseHandle(hToken);

    return isSuccess;
}


シャットダウンではなく、サスペンドさせたい場合には、
1.以下を追加

#include <powrprof.h>   //SetSuspendState

#pragma comment(lib, "PowrProf.lib")

2.以下を変更

        //if (!InitiateSystemShutdownExW(nullptr, nullptr, 0, FALSE, FALSE, SHTDN_REASON_FLAG_USER_DEFINED))
        if (!SetSuspendState(TRUE, FALSE, TRUE))

コメントは、適宜変更してください。

この実行ファイルでサスペンドさせると、復帰した時に、スタートメニューが表示されないので、スッキリしています。