もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
UIのあるwin32アプリのウインドウを最前面に持ってくるのは、win32APIのSetForegroundWindow()
というAPIを使えばできていた。
が、UWPアプリはその方法ではできなかった。
※UWPのアプリは、ApplicationFrameHost.exe
というプロセスが、実体のexe(Windowsの設定の場合はSystemSettings.exe
)を包んでいる??ために、SystemSettings.exe
のハンドルを取ってきてSetForegroundWindow()をしても、前面に出てくれなかった。
また、ApplicationFrameHost.exe
のハンドルを取ってきてSetForegroundWindow()をすると、「直前にフォーカスされてたUWPアプリのウインドウ」が最前面にくるという動きをして、狙ったUWPのウインドウを前面に持ってこれなかった。
なんとか、狙ったUWPウインドウを前面に持ってきたい。
やりかた
Launcher.LaunchUriAsync()
と
AppDiagnosticInfo
のLaunchAsync()
を使う。
今回は、UWPアプリ=Windowsの設定アプリでやってみた。
Windowsの設定アプリは、
ms-settings:なんとか
で、開きたい設定画面を指定して開くことができる。そのms-settings:を使って、今回は、
Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam"))
で、カメラ設定画面を開いて、- その画面を、
app.LaunchAsync()
で、前にもってくる
ということをやってみた。
実験コード1(LaunchAsync()で前に出す)
今回、UWPのAPIを使うために、ターゲットをWindowsにして、ターゲットのOSを10.0.22000.0にした。
using System; using System.Collections.Generic; using System.Threading; using Windows.System; using Windows.System.Diagnostics; namespace ProcessListUpByUwpApi; class Program { static async Task Main(string[] args) { while (true) { Console.WriteLine("処理スタート"); await LaunchSettingWindow(); Console.WriteLine("設定を開きました"); await BringFront(); Console.WriteLine("設定を前に持ってきました"); await Task.Delay(5000); } } static async Task LaunchSettingWindow() { // https://learn.microsoft.com/ja-jp/windows/uwp/launch-resume/launch-settings-app#calling-launchuriasync await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam")); } static async Task BringFront() { var uwpApps = await AppDiagnosticInfo.RequestInfoAsync().AsTask(); if (uwpApps is null) return; var app = uwpApps.Where(x => x.AppInfo.AppUserModelId == "windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel") .FirstOrDefault(); if (app is null) return; // https://learn.microsoft.com/ja-jp/uwp/api/windows.system.appdiagnosticinfo.launchasync?view=winrt-26100 await app.LaunchAsync().AsTask(); } }
実験コード2(PowerShellでStart-ProcessでAUMIDを指定して前面に出す)
using System.Diagnostics; using Windows.System; namespace ProcessListUpByUwpApi; class Program { static async Task Main(string[] args) { while (true) { await Task.Delay(1000); await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam")); await Task.Delay(1000); } } static async Task BringFront() { GetPowerShellCommandReturn("Start-Process shell:AppsFolder\\windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel"); } static string GetPowerShellCommandReturn(string psCommandWithArgs) { var psInfo = new ProcessStartInfo(); psInfo.FileName = @"PowerShell.exe"; psInfo.CreateNoWindow = true; psInfo.WindowStyle = ProcessWindowStyle.Hidden; psInfo.UseShellExecute = false; psInfo.Arguments = psCommandWithArgs; psInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト psInfo.RedirectStandardError = true; // 標準エラー出力をリダイレクト var p = Process.Start(psInfo); string all = p.StandardOutput.ReadToEnd(); // 標準出力の読み取り return all; } }
実験コード3(PowerShellでStart-ProcessでURIを叩いて前面に出す)
using System.Diagnostics; using Windows.System; namespace ProcessListUpByUwpApi; class Program { static async Task Main(string[] args) { while (true) { await BringFront(); await Task.Delay(1000); } } static async Task BringFront() { GetPowerShellCommandReturn("Start-Process ms-settings:privacy-webcam"); } static string GetPowerShellCommandReturn(string psCommandWithArgs) { var psInfo = new ProcessStartInfo(); psInfo.FileName = @"PowerShell.exe"; psInfo.CreateNoWindow = true; psInfo.WindowStyle = ProcessWindowStyle.Hidden; psInfo.UseShellExecute = false; psInfo.Arguments = psCommandWithArgs; psInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト psInfo.RedirectStandardError = true; // 標準エラー出力をリダイレクト var p = Process.Start(psInfo); string all = p.StandardOutput.ReadToEnd(); // 標準出力の読み取り return all; } }
備考
Windows 24H2以降、うまく動かない(前面に出てくれない)気がする、、、
Windows 設定アプリの起動
下記に一覧がある。