C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

「ユーザーの切り替え」を知りたい /りんく (19/11/18(Mon) 10:27) #93059
Re[1]: 「ユーザーの切り替え」を知りたい /とっちゃん (19/11/18(Mon) 13:14) #93065
  └ Re[2]: 「ユーザーの切り替え」を知りたい /りんく (19/11/18(Mon) 14:13) #93069
    ├ Re[3]: 「ユーザーの切り替え」を知りたい /りんく (19/11/18(Mon) 15:09) #93071
    └ Re[3]: 「ユーザーの切り替え」を知りたい /とっちゃん (19/11/19(Tue) 12:10) #93081
      └ Re[4]: 「ユーザーの切り替え」を知りたい /りんく (19/12/02(Mon) 16:03) #93283 解決済み


親記事 / ▼[ 93065 ]
■93059 / 親階層)  「ユーザーの切り替え」を知りたい
□投稿者/ りんく (1回)-(2019/11/18(Mon) 10:27:31)

分類:[C#] 

Visual Studio 2017 C# WPF

前提条件
・WindowsにユーザAとユーザBが登録されている状態
・ログイン機能のあるソフト(以下、当ソフト)

手順
1.ユーザAでWindowsにログインし、当ソフトを起動
2.当ソフトでログインをする(ID、パスワードを入力してメインメニューに遷移)
3.Windowsの「ユーザーの切り替え」機能を使用してユーザBにログイン
4.当ソフトでログインをする(ID、パスワードを入力してメインメニューに遷移)

やりたいこと
3または4が実行されたときに2でログインしているユーザAをログアウトしたい


Windowsの「ユーザーの切り替え」が実行されたかどうかを知ることができれば
実現できるかと思うのですが、知ることはできるのでしょうか?

当ソフト起動時に「System.Environment.UserName」で名前を保持しておき
「System.Environment.UserName」を取得するポーリングを実行し
起動時のUserNameとポーリングでのUserNameが不一致だったらログアウトするとしてみたのですが
ユーザーを切り替えてもポーリング内のUserNameは起動時のUserNameと同じでした。
今現在、ログインしているユーザーのユーザー名を取得することはできないのでしょうか?

どのようにすれば実現できるのか、わかる方がおられましたら、ご教授願います。
[ □ Tree ] 返信 編集キー/

▲[ 93059 ] / ▼[ 93069 ]
■93065 / 1階層)  Re[1]: 「ユーザーの切り替え」を知りたい
□投稿者/ とっちゃん (643回)-(2019/11/18(Mon) 13:14:39)
No93059 (りんく さん) に返信

> 当ソフト起動時に「System.Environment.UserName」で名前を保持しておき
> 「System.Environment.UserName」を取得するポーリングを実行し
> 起動時のUserNameとポーリングでのUserNameが不一致だったらログアウトするとしてみたのですが
> ユーザーを切り替えてもポーリング内のUserNameは起動時のUserNameと同じでした。
> 今現在、ログインしているユーザーのユーザー名を取得することはできないのでしょうか?
>
> どのようにすれば実現できるのか、わかる方がおられましたら、ご教授願います。

あるアカウントで起動したプログラムは別のアカウントを認識できません。

この場合、ユーザーAでログインした状態でアプリを起動しても
ユーザーBのログイン状況内ではプログラムは起動していない状態です。

タスクマネージャで見てみればすぐにわかります。

そのため、ポーリングしても判別はできません。


最初の一歩としてはここかな?(日本語はありません)
https://docs.microsoft.com/en-us/windows/win32/shell/fast-user-switching?WT.mc_id=DT-MVP-32182

あるユーザーがログイン状態のまま別のユーザーに切り替えできる仕組みを「Fast User Switching」と呼びます。

通常別ユーザーと切り替えたなどは必要ありませんが、それを識別できる必要がある場合メッセージを受け取れるように
する仕組みが用意されています。

Windows API と、メッセージを受け取れる必要があるので、それなり以上に面倒な実装になります。


ところで、アプリのログイン機能というのはそのマシンの中に情報を持っているのでしょうか?
ログインのアカウントが変わると、AppData フォルダは別物になります。また、ドキュメントなどのフォルダは別になります。
そのあたりは問題はありませんか?

[ 親 93059 / □ Tree ] 返信 編集キー/

▲[ 93065 ] / ▼[ 93071 ] ▼[ 93081 ]
■93069 / 2階層)  Re[2]: 「ユーザーの切り替え」を知りたい
□投稿者/ りんく (3回)-(2019/11/18(Mon) 14:13:23)
2019/11/18(Mon) 15:04:36 編集(投稿者)
2019/11/18(Mon) 15:03:29 編集(投稿者)

No93065 (とっちゃん さん) に返信
回答ありがとうございます。

> Windows API と、メッセージを受け取れる必要があるので、それなり以上に面倒な実装になります。
教えていただいたURLからWM_WTSSESSION_CHANGEについて調べてみました。
ウィンドウメッセージでWM_WTSSESSION_CHANGEが受信できたので
ログアウト処理を実行することができました。

> ところで、アプリのログイン機能というのはそのマシンの中に情報を持っているのでしょうか?
> ログインのアカウントが変わると、AppData フォルダは別物になります。また、ドキュメントなどのフォルダは別になります。
> そのあたりは問題はありませんか?
すみません、よくわかっていないのですがアプリ自体は以下のようになっています。

アプリはインストーラにより「すべてのユーザー」でインストールされます。
アプリの下回り処理は一緒にインストールされるサービスが行うようになっているため、
ユーザ関係なく処理は実行されると考えています。
ログインについてはアプリが管理するデータベースに保存されているIDとパスワードでログインします。
また、AppData フォルダやドキュメントフォルダなどは参照していません。

回答になっているでしょうか?
[ 親 93059 / □ Tree ] 返信 編集キー/

▲[ 93069 ] / 返信無し
■93071 / 3階層)  Re[3]: 「ユーザーの切り替え」を知りたい
□投稿者/ りんく (5回)-(2019/11/18(Mon) 15:09:51)
WM_WTSSESSION_CHANGEを受信した際、
wParam にある詳細については判定していないのですが
@「ユーザAでログアウト、再度ユーザAでログイン」のときと
A「ユーザAでログアウト、ユーザBでログイン」のときと wParam の値が変わりませんでした。
Aのときにしか「WTS_CONSOLE_DISCONNECT」は発生しないと思ったのですが
@でもAでも発生していました。
※参考にしたページのURLが載せられないようです。。

wParamは下記の値が順番に入ってきました。
WTS_CONSOLE_DISCONNECT=2
WTS_SESSION_LOCK=7
WTS_CONSOLE_CONNECT=1
WTS_SESSION_UNLOCK=8
[ 親 93059 / □ Tree ] 返信 編集キー/

▲[ 93069 ] / ▼[ 93283 ]
■93081 / 3階層)  Re[3]: 「ユーザーの切り替え」を知りたい
□投稿者/ とっちゃん (644回)-(2019/11/19(Tue) 12:10:55)
No93071 (りんく さん) に返信
> WM_WTSSESSION_CHANGEを受信した際、
> wParam にある詳細については判定していないのですが
> @「ユーザAでログアウト、再度ユーザAでログイン」のときと
> A「ユーザAでログアウト、ユーザBでログイン」のときと wParam の値が変わりませんでした。
> Aのときにしか「WTS_CONSOLE_DISCONNECT」は発生しないと思ったのですが
> @でもAでも発生していました。
> ※参考にしたページのURLが載せられないようです。。
>
> wParamは下記の値が順番に入ってきました。
> WTS_CONSOLE_DISCONNECT=2
> WTS_SESSION_LOCK=7
> WTS_CONSOLE_CONNECT=1
> WTS_SESSION_UNLOCK=8

どのセッションの状態が変わったかは、lParam で判断します。
wParam は、何が変わったかという情報です。
WTS_CONSOLE_XXXX なら、コンソールが接続された・接続解除されたですし、
WTS_SESSION_XXXX なら、セッションがXXXX されたという通知です。

具体的にどのコンソール(=セッション)かは、lParam で判断します。


> Aのときにしか「WTS_CONSOLE_DISCONNECT」は発生しないと思ったのですが

DISCONNECT が呼ばれるのは、Aのコンソールが切り離されたタイミングすなわち、別のアカウントでログオン処理を開始したタイミングです。
あとは、もしかしたら画面ロックでも呼ばれるかもしれません。

さて本題。

現状見えている範囲から類推される問題点は以下のようなものでしょうか?

1. 「すべてのユーザー」でインストールしたアプリがある。
2. すべてのユーザーで共通利用しているDBがある。
3. DBへのアクセス(ログイン)は複数同時で行うことはできず、誰か一人だけが行える。
4. 現在のユーザーでログオンしたまま、別のユーザーでログオンしてアプリを起動するとDBへのアクセスが複数で行われてしまう。

上記で認識があっているとしたら、WTS_CONSOLE_DISCONNECT を受け取ったときに、
そのユーザーはDBアクセスをログオフするとすればいいと思います。
そのあと、WTS_CONSOLE_CONNECT が来たら再びDBアクセスできるようにログオンすれば解決すると思います。

[ 親 93059 / □ Tree ] 返信 編集キー/

▲[ 93081 ] / 返信無し
■93283 / 4階層)  Re[4]: 「ユーザーの切り替え」を知りたい
□投稿者/ りんく (6回)-(2019/12/02(Mon) 16:03:23)
No93081 (とっちゃん さん) に返信
返信遅くなり申し訳ありません。

こちらでいろいろ話し合った結果、
「WM_WTSSESSION_CHANGE」を受信した時点でログアウトしてしまって良いということんになり
「wParam」の判定は不要になりました。
ご教授いただいたのに申し訳ありません。
ありがとうございました。
解決済み
[ 親 93059 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -