もくじ
やりたいこと
自分以外のアプリのウインドウが、ほかのウインドウの後ろに回っていたら、最前面に表示させたい。
このページに、様々なやり方が書かれているので、そちらを見ればわかってしまうが、自分でもやって試したときのメモ。
https://dobon.net/vb/dotnet/process/appactivate.html
やり方
Microsoft.VisualBasic.Interaction.AppActivate()
を使う。
- 最前面に表示させたいアプリ(プロセス)のプロセス名を調べておく。
- その名前を
Process.GetProcessesByName()
に渡して、プロセス(の配列)を取得 - 取得したプロセスに対して、
Microsoft.VisualBasic.Interaction.AppActivate()
を行う。
※他にもやり方はいろいろある様子。上のページを参照。
サンプル
例えば、自分と同じプロセス名を持つプロセス(同じexeを二つ起動してるときなど)を取得してきて、全部を最前面に出す、ということをしようと思うと、下記のようになる。
var current = Process.GetCurrentProcess();
Process.GetProcessesByName(current.ProcessName)
.ToList()
.ForEach(p => Microsoft.VisualBasic.Interaction.AppActivate(p.Id));
取得したプロセスの情報を使って対象を絞ってやれば、同じexeがすでに起動してたら、そっち側を最前面にもってくる、みたいなこともできる。
var current = Process.GetCurrentProcess();
Process.GetProcessesByName(current.ProcessName)
.Where(p => p.Id != current.Id) // ←自分以外を指定(プロセス名は同じでも、プロセスIDはそれぞれ異なる)
.ToList()
.ForEach(p => Microsoft.VisualBasic.Interaction.AppActivate(p.Id));
注意
普通にウインドウを持ってるアプリを普通に起動して、そこから上のようにしてやれば、ほかのプロセスを最前面にもってくる、ということはできるっぽい。
ただし制限事項もあるようで、その辺が下記にまとめられていた。
https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-setforegroundwindow#remarks
上に参考であげさせて頂いているdobon.netのページでも、「アクティブ化することができないときのやり方」ということでまとめられているくらいなので、この条件の何かに引っかかってうまくアクティブ化できないことはあるんだろうと思う。
私個人的には、これまで最前面に持ってこれなかったことはあまりなかったが、1回だけ、どうしても最前面に出せないこケースがあった。
具体的には、
Windows10で、アクションセンターの中のトーストを押して起動したアプリのWindowが表示される前(Loadedイベントの中)でAppActivate()
をやっても、ほかのウインドウを最前面に出すことができなかった。
(記憶がはっきりしないが、たしかそのケースでも、一度ウインドウがでてきて、ボタンを押したときにAppActivate()
をすると、うまくいっていた)
上の制限事項をまとめた備考から考えるに、トーストが押されたことを検知してアプリを呼び出してくれるWindowsの機能が「バックグラウンドプロセス」で、バックグラウンドプロセスから呼んだプロセスの中では「ほかのウインドウをアクティブ化」するような処理はできない、ということなんだろう、と予測した。(本当にそうかどうかは不明...)