【VC++】からWscript.Shellを呼び出してWindowsをスタンバイ状態にする




ブラウザでダウンロード
シャットダウンダイアログを表示してキーストロークを送る
【VBS & PHP】スクリプトからスタンバイ状態にする で実現した方法を VC++ で行います。

要するに、VC から Shell.Application と Wscript.Shell を呼び出すわけです。
( Sleep のみ Win32 API です )

キーストロークは、Win32 API でも送れますが、こちらのほうが簡単で実績もあるので。
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <stdio.h>

#define GetFreeSpace GetFreeSpaceEx

#import "SHELL32.dll"
#import "wshom.ocx"

Shell32::IShellDispatchPtr pShell = NULL;
IWshRuntimeLibrary::IWshShell3Ptr pWshShell = NULL;

// *********************************************************
// Windows アプリケーションとしてのエントリポイント
// Link.exe で /SUBSYSTEM:WINDOWS がデフォルトで
// 指定される事になります
// *********************************************************
int APIENTRY _tWinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine,
	int nCmdShow
)
{
	CoInitialize(NULL);

	try {
		HRESULT hr;
		hr = pShell.CreateInstance("Shell.Application");
		if ( FAILED(hr) ) {
			_com_issue_error(hr);
		}
		pShell->ShutdownWindows();
		pShell.Release();
	}
	catch (_com_error &e)
	{
	}

	Sleep(1000);

	try {
		HRESULT hr;
		hr = pWshShell.CreateInstance("Wscript.Shell");
		if ( FAILED(hr) ) {
			_com_issue_error(hr);
		}

		_variant_t Title = "Windows のシャットダウン";

		pWshShell->AppActivate(&((VARIANT)Title));

		Sleep(1000);

		_bstr_t Keys = "{DOWN}{DOWN}{DOWN}{ENTER}";

		pWshShell->SendKeys( Keys );

		pWshShell.Release();
	}
	catch (_com_error &e)
	{
	}


	CoUninitialize();

	return 0;
}
見たままで、VBScript と同じ処理です。

#define GetFreeSpace GetFreeSpaceEx は、wshom.tlh と wshom.tli の中に同名の
メソッドがあって、コンパイルがエラーになるのでマクロ名を再定義しています。
( ビルドには関係無いので問題ありません )


_variant_t は、この手の処理を行う時の _bstr_t の仲間で、この二つのクラスが
無いと、COM を呼び出すのは無理です。

この環境では、マルチバイト( SHIFT_JIS ) ですが、クラス内は Unicode なので
何も気にしないでコードを書けます。