2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[C#/WPF] ユーザーがログイン/ログアウト、PCをシャットダウン等したときになにかしたい

Last updated at Posted at 2020-06-29

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

類似記事

やりたいこと

アプリ起動中に、下記のような操作でユーザーがシャットダウンやログオフなどをしたとき、またその逆のログインしなおしたとき等に、アプリ側でそれを知って、しかるべき処理をしたい。(何かのサーバーやデバイスと通信するようなアプリであれば、一旦通信を終わらせたり、逆に再開したりしたい)

image.png
image.png

やり方

SystemEventsにある各種イベントを利用する。
↓この辺を使う。
image.png
MS資料

実験コード

実験コード抜粋.cs
// 何のイベントハンドラが動いたのか、またイベントのArgの中身を表示する。
private void root_Loaded(object sender, RoutedEventArgs e)
{
    SystemEvents.SessionSwitch          += ((sender, e) => { AddLog("SessionSwitch       :" + e.Reason.ToString()); });
    SystemEvents.SessionEnding          += ((sender, e) => { AddLog("SessionEnding       :" + e.Reason.ToString()); });
    SystemEvents.SessionEnded           += ((sender, e) => { AddLog("SessionEnded        :" + e.Reason.ToString()); });
    SystemEvents.PowerModeChanged       += ((sender, e) => { AddLog("PowerModeChanged    :" + e.Mode.ToString()); });
    SystemEvents.EventsThreadShutdown   += ((sender, e) => { AddLog("EventsThreadShutdown:" + e.ToString()); });
}

実験アプリ仕様:
アプリを起動したまま、シャットダウンやらログオフやらをすると、画面表示&exeと同じ階層にログを出力してくれる仕組み。(ListBoxにログを出して、なんのイベントが来たか見ようとしたが、それだとシャットダウンやログアウトしたときに実験アプリが終わってしまい、見れないので、ログファイルを残すようにした)

ロック、再度サインイン

ロックして、再度サインインしたらどうなるか?
image.png

結果
SessionSwitchイベントで、e.ReasonSessionLockSessionUnlockがきた。
image.png

他のユーザー切り替えして、戻ってくる

他のユーザーに一旦切り替えて、また自分のユーザーに戻ってくる(サインインしなおす)
(=FUS(Fast User Switching)→あるユーザーがログインしたまま、別のユーザーもログインしてるイメージ)
image.png

結果
SessionSwitchイベントで、下記の順番で来た。(下から順番に)

image.png
※今回は自分のPCで直接ユーザー切り替え操作を行ったが、もしこれがリモートデスクトップでの接続だったら、ConsoleConnectConsoleDisconnectが、RemoteConnectRemoteDisconnectになるっぽい。

サインアウト(ログアウト、ログオフともいう)

サインアウトする。
image.png

結果
SessinEndingLogoffと、そのあとにSessinIndedLogoffが来た。
image.png

スリープ、復帰(サスペンド、レジュームともいう)

スリープさせる。
image.png

結果
下記の順で来た。(下から順番に)
image.png

シャットダウン

シャットダウンする。
image.png

結果
SessionEndingSystemShutdownのあとに、SessionEndedSystemShutdownが来た。
image.png

C++で似たことを試した

下記記事で、Wndprocにくる「電源イベント」をフックすることで、サスペンド⇔レジューム等のイベントを取るのを試した。

電源イベントではログオフ、ログオンは取れないが、スリープやサスペンド、レジュームは取れるので、似たことができると思う。(試してないけどたぶん、WM_POWERBROADCASTじゃなくて違うWMイベントをとれば、セッション系イベントも取れると思う)

参考

SystemEvents.PowerModeChanged イベント
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.win32.systemevents.powermodechanged?view=dotnet-plat-ext-3.1

上記ページの左側に、イベントが一覧になってるので、そこから必要なイベントに飛べる。
image.png

イベントの引数を見て、詳細な情報(例えば、SessionSwitchであれば、suspendなのか、resumeなのか、など)を知る必要があるが、そのへんは、同じページの下の方に、〇〇Argsへのリンクが載ってるので、そこから飛んで、引数を調べればいい。
image.png

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?