- PR -

C#を使用してのPC電源OFF

1
投稿者投稿内容
うちうせん
ベテラン
会議室デビュー日: 2003/08/08
投稿数: 96
お住まい・勤務地: 福岡県
投稿日時: 2006-02-14 17:50
VC#2002を使用してPCの電源を落とすソフトを作りたいと思っています。
Win32APIを使用すればできそうだとは思うのですが、C#だけで実現できないでしょうか?
アドバイスお願いします。

-------------------
WindowsXP Pro
VC#2002
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-14 17:59
引用:

しゅうさんの書き込み (2006-02-14 17:50) より:

VC#2002を使用してPCの電源を落とすソフトを作りたいと思っています。
Win32APIを使用すればできそうだとは思うのですが、C#だけで実現できないでしょうか?
アドバイスお願いします。


電源を落とすのではなく、Windows を終了させる、かな?
C# というか、.NET Framework だけでは無理です。

ExitWindowsEx 関数か WMI の Shutdown メソッドになるでしょう。
ご存知ないのであれば、特権モードについても調べておく必要がありそうです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-02-14 23:40
バイナリはあるけど、ソースコードがない。。。
手本にした、C++ のコード
ん〜、なんか、例外を goto の代わりに使うという、アホなことをやってる...

必要最小限のことしかしていませんので、pinvoke.com からそれぞれの宣言をコピってくれば、あっという間にできあがります。
コード:
int main(int argc, char* argv[])
{
	void	GetErrorMessage(char *message_buffer,
				int buffer_length,
				int err);

	HANDLE				hTkn;				// アクセストークンハンドル
	TOKEN_PRIVILEGES	tkp;				// 特権
	DWORD				ret;				// APIの戻り値
	UINT				flag;				// シャットダウンの種別

	flag = EWX_POWEROFF | 0x10/*EWX_FORCEIFHUNG*/;	// デフォルト(電源断)
	if (argc == 1) {
		printf("Shutdown {LOGOFF | REBOOT | OFF}\n"
			"\tLOGOFF ... Logoff from system\n"
			"\tREBOOT ... Reboot the system\n"
			"\tOFF    ... Power off the system (default)\n");
		exit(0);

	} else if (argc > 1) {
		if (!strcmp(argv[1], "LOGOFF")) {
			flag = EWX_LOGOFF;

		} else if (!strcmp(argv[1], "REBOOT")) {
			flag = EWX_REBOOT | 0x10/*EWX_FORCEIFHUNG*/;

		} else if (!strcmp(argv[1], "OFF")) {
			flag = EWX_POWEROFF | 0x10/*EWX_FORCEIFHUNG*/;

		} else{
			printf("Shutdown {LOGOFF | REBOOT | OFF}\n"
				"\tLOGOFF ... Logoff from system\n"
				"\tREBOOT ... Reboot the system\n"
				"\tOFF    ... Power off the system (default)\n");
			exit(0);
		}
	}

	try {
		// このプロセスのアクセストークンを取得する
		ret = OpenProcessToken(GetCurrentProcess()
			, (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), &hTkn);
		if (ret == 0) {
			char	msg[256];
			string	str("OpenProcessToken Function returns rror status\n");
			GetErrorMessage(msg, sizeof(msg), GetLastError());
			str.append(msg);
			throw Exception(str);
		}

		// プロセス実行に必要なアクセス権限への接続子を取得する
		ret = LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
		if (ret == 0) {
			char	msg[256];
			string	str("LookupPrivilegeValue Function returns error status\n");
			GetErrorMessage(msg, sizeof(msg), GetLastError());
			str.append(msg);
			throw Exception(str);
		}

		// 特権を変更する
		tkp.PrivilegeCount = 1;			// SE_SHUTDOWN_NAME のみを変更する
		tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;	// 「可能」にする
		ret = AdjustTokenPrivileges(hTkn, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
		if (ret == 0) {
			char	msg[256];
			string	str("AdjustTokenPrivileges Function returns error status\n");
			GetErrorMessage(msg, sizeof(msg), GetLastError());
			str.append(msg);
			throw Exception(str);
		}

		ret = ExitWindowsEx(flag, 0);
		if (ret == 0) {
			char	msg[256];
			string	str("ExitWindowsEx Function returns error status\n");
			GetErrorMessage(msg, sizeof(msg), GetLastError());
			str.append(msg);
			throw Exception(str);
		}

	} catch (Exception &e) {
		printf("%s\n", e.Message.c_str());
	}

	if (ret != 0) {
		printf("All done in success...\n");
	}
	return (ret == 0);

}


ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2006-02-15 00:41
C# WMI です。

コード:
static void Main(string[] args)
{
    System.Management.ConnectionOptions options
        = new System.Management.ConnectionOptions();
    options.EnablePrivileges = true;
    System.Management.ManagementScope scope
        = new ManagementScope("\\\\.\\root\\CIMV2", options);
    scope.Connect();
    System.Management.ObjectQuery query 
        = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
    System.Management.ManagementObjectSearcher searcher
        = new System.Management.ManagementObjectSearcher(scope, query);
    System.Management.ManagementObjectCollection OSs
        = searcher.Get();
    foreach (System.Management.ManagementObject OS in OSs)
    {
        OS.InvokeMethod("Shutdown", null);
    }
}



例外処理一切行っていないので、そこんとこよろしく。

初めて C# で Programming してみましたが、案外簡単かけちゃうもんですね。
ということで、まずいとこあったら バシバシ 指摘してくださいませ。
YAS
ベテラン
会議室デビュー日: 2006/02/15
投稿数: 59
投稿日時: 2006-02-15 01:00
いんちきですが,
コマンドプロンプトで「shutdown -s」を実行するというのはだめですか?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-15 02:05
書くのが面倒なので、

  Google 検索結果

最近コードばかり書いて回答してますから、たまには...w

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
うちうせん
ベテラン
会議室デビュー日: 2003/08/08
投稿数: 96
お住まい・勤務地: 福岡県
投稿日時: 2006-02-15 09:11
[解決]
いろいろとアドバイスありがとうございました。
ExitWindowsEx関数は使ったことがあったため、VC++.NetでDll化してC#から呼ぶように作ったところなんとか成功したようです。
WMIはまだ未知なので機会があれば習得してみようかと思います。

P.S.
 98のころはExitWindowsEx関数だけでよかったのに、2000以降になったら特権なんてものがからんでくるんですね・・・。
 サンプルコピペだったためまったく理解はできてませんが><
1

スキルアップ/キャリアアップ(JOB@IT)