🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

ウィンドウ

コンピューター用語において、ウィンドウとはユーザとプログラムのやり取りを可能にするGUIの枠組みのことをいいます。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

2回答

27709閲覧

Powershellでのアクティブウィンドウ切り替え

empty

総合スコア1

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

ウィンドウ

コンピューター用語において、ウィンドウとはユーザとプログラムのやり取りを可能にするGUIの枠組みのことをいいます。

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

1クリップ

投稿2021/03/22 13:31

ネットを調べたりしましたが、解決できませんでした。
助けをお借りしたく、よろしくお願いします。

前提・実現したいこと

Powershellを使用して、最前面ウィンドウの切り替えを行いたい。

元々「メモ帳」「コマンドプロンプト」が起動してあり、「コマンドプロンプト」が最前面ウィンドウ

これを以下のようにしたいです。
「メモ帳」を最前面ウィンドウ、30秒後、「コマンドプロンプト」を最前面ウィンドウに戻す

発生している問題・エラーメッセージ

「コマンドプロンプト」を最前面ウィンドウに戻そうとしましたが、「メモ帳」に隠れたままで戻りませんでした。

該当のソースコード

add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms

$ps = Get-Process | Where-Object {$_.Name -match "notepad"}
foreach($process in $ps){
Microsoft.VisualBasic.Interaction::AppActivate($process.ID);
}

Start-Sleep -s 30

$ps = Get-Process | Where-Object {$_.Name -match "cmd"}
foreach($process in $ps){
Microsoft.VisualBasic.Interaction::AppActivate($process.ID);
}

試したこと

以下に変更しましたが、症状は同じで解決しませんでした。

Start-Sleep -s 30
Microsoft.VisualBasic.Interaction::AppActivate("cmd.exe")

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

empty

2021/03/31 12:51

Hey_CHさん 回答ありがとうございます。 思っていたよりもボリュームがあるようで、驚きました。 ご案内頂いたページを読み込んでリベンジします。
Hey_CH

2021/03/31 14:28

具体的には「該当のソースコード」の3行目に以下($cscode =...)を追加して、foreachの中身を「$Win32::ActiveWindow($process.MainWindowHandle);」みたいにして呼び出してみてください。 $cscode = @" ここにdobon.netさんのC#のコードをコピペ "@ $Win32 = add-type -memberDefinition $cscode -name "Win32ApiFunctions" -passthru
empty

2021/04/01 11:44

Hey_CHさん 具体的な内容を記載して頂き、助かります。ありがとうございました。 記載通りにやってみたのですが、なかなかうまくいきませんでした。 PS1ファイルは、「該当のソースコード」を記載頂いた通りに修正し、 BATファイルからキックさせたり、Powershellから実行したりしましたが、 それぞれ、コマンドプロンプトが起動・Powershellが起動、30秒後に閉じるという動作でした。 そもそも、キックのやり方が違うのでしょうか。 教えて頂いたHPを再度読んで、挑戦してみます。
guest

回答2

0

「該当のソースコード」を(長いんで30秒→3秒に変更だけしましたが)スクリプト化し、コマンドプロンプトから実行したところ
すぐメモ帳が最前面に出て、3秒後にコマンドプロンプト画面が最前面となりました。

コードは間違っていないようです。

もしかしてpowershell_ise(ないしほかのエディタ・ターミナルソフト)から実行してませんか?

ちなみに、11行目の

powershell

1$_.Name -match "cmd"

powershell

1$_.Name -match "powershell_ise"

に変更したところ、ISEからも狙い通りの動作となりました。

PSVersion 5.1.18362.752
BuildVersion 10.0.18362.752

投稿2021/04/06 23:36

satocha

総合スコア336

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

empty

2021/04/07 14:19

satochaさん こんばんは、回答をありがとうございます。 実行方法ですが、BATファイルからPS1ファイルを指定して実行しています。 BATファイルの中身 @echo off powershell -NoProfile -ExecutionPolicy Unrestricted ".\AAActive.ps1" exit /b 0 PS1ファイルの中身は、Hey_CHさんの回答を丸パクしています。 実行環境によるものなのかなと、苦闘中です。 Powershell バージョン 7.1.3
satocha

2021/04/08 01:22

そのバッチはどうやって動かしているのでしょう。 要は $ps = Get-Process | Where-Object {$_.Name -match "cmd"} で、最前面にすべきウインドウが取れているかどうか、確認したほうがいいと思います。
empty

2021/04/08 14:27

satochaさん こんばんは。 BATファイルは、手動ダブルクリックで実行しています。
Hey_CH

2021/04/08 15:16

僕の環境では、質問欄のコードではメモ帳が前面に表示されるけど、コマンドプロンプトはタスクバーでオレンジになるだけ。 それで、dobon.netさんのコードパクったらメモ帳が前面に表示された後、コマンドプロンプトが前面に表示されるようになりました。 これは、BATファイルをダブルクリックして実行したときも同じ挙動(前もって起動してたコマンドプロンプトが前面に表示される)になりました。 実行環境によって様々みたいですね~。
guest

0

ベストアンサー

丸パクリなので、このコードを使用する場合、dobon.netさんを確認してください。
質問者さんとコードが違う部分が無いか確認のために回答として記述します。
(これで動かない場合、恐らく環境が違うと思うので、僕の方では検証できません。)

PowerShell

1add-type -AssemblyName microsoft.VisualBasic 2add-type -AssemblyName System.Windows.Forms 3 4 5$cscode = @" 6public static void ActiveWindow(IntPtr hWnd) 7{ 8 if (hWnd == IntPtr.Zero) 9 { 10 return; 11 } 12 13 //ウィンドウが最小化されている場合は元に戻す 14 if (IsIconic(hWnd)) 15 { 16 ShowWindowAsync(hWnd, SW_RESTORE); 17 } 18 19 //AttachThreadInputの準備 20 //フォアグラウンドウィンドウのハンドルを取得 21 IntPtr forehWnd=GetForegroundWindow(); 22 if (forehWnd == hWnd) 23 { 24 return; 25 } 26 //フォアグラウンドのスレッドIDを取得 27 uint foreThread = GetWindowThreadProcessId(forehWnd, IntPtr.Zero); 28 //自分のスレッドIDを収得 29 uint thisThread = GetCurrentThreadId(); 30 31 uint timeout = 200000; 32 if (foreThread != thisThread) 33 { 34 //ForegroundLockTimeoutの現在の設定を取得 35 //Visual Studio 2010, 2012起動後は、レジストリと違う値を返す 36 SystemParametersInfoGet(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, 0); 37 //レジストリから取得する場合 38 //timeout = (uint)Microsoft.Win32.Registry.GetValue( 39 // @"HKEY_CURRENT_USER\Control Panel\Desktop", 40 // "ForegroundLockTimeout", 200000); 41 42 //ForegroundLockTimeoutの値を0にする 43 //(SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)を使いたいが、 44 // timeoutがレジストリと違う値だと戻せなくなるので使わない 45 SystemParametersInfoSet(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0); 46 47 //入力処理機構にアタッチする 48 AttachThreadInput(thisThread, foreThread, true); 49 } 50 51 //ウィンドウをフォアグラウンドにする処理 52 SetForegroundWindow(hWnd); 53 SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, 54 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); 55 BringWindowToTop(hWnd); 56 ShowWindowAsync(hWnd, SW_SHOW); 57 SetFocus(hWnd); 58 59 if (foreThread != thisThread) 60 { 61 //ForegroundLockTimeoutの値を元に戻す 62 //ここでも(SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)は使わない 63 SystemParametersInfoSet(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, timeout, 0); 64 65 //デタッチ 66 AttachThreadInput(thisThread, foreThread, false); 67 } 68} 69 70[DllImport("user32.dll")] 71[return: MarshalAs(UnmanagedType.Bool)] 72private static extern bool SetForegroundWindow(IntPtr hWnd); 73 74[DllImport("user32.dll")] 75private static extern IntPtr GetForegroundWindow(); 76 77[DllImport("user32.dll", SetLastError = true)] 78[return: MarshalAs(UnmanagedType.Bool)] 79private static extern bool BringWindowToTop(IntPtr hWnd); 80 81[DllImport("user32.dll")] 82static extern IntPtr SetFocus(IntPtr hWnd); 83 84[DllImport("user32.dll", SetLastError = true)] 85[return: MarshalAs(UnmanagedType.Bool)] 86private static extern bool SetWindowPos(IntPtr hWnd, 87 int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags); 88 89private const int SWP_NOSIZE = 0x0001; 90private const int SWP_NOMOVE = 0x0002; 91private const int SWP_NOZORDER = 0x0004; 92private const int SWP_SHOWWINDOW = 0x0040; 93private const int SWP_ASYNCWINDOWPOS = 0x4000; 94private const int HWND_TOP = 0; 95private const int HWND_BOTTOM = 1; 96private const int HWND_TOPMOST = -1; 97private const int HWND_NOTOPMOST = -2; 98 99[DllImport("user32.dll")] 100[return: MarshalAs(UnmanagedType.Bool)] 101private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 102[DllImport("user32.dll")] 103[return: MarshalAs(UnmanagedType.Bool)] 104private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); 105 106private const int SW_SHOWNORMAL = 1; 107private const int SW_SHOW = 5; 108private const int SW_RESTORE = 9; 109 110[DllImport("user32.dll")] 111[return: MarshalAs(UnmanagedType.Bool)] 112private static extern bool IsIconic(IntPtr hWnd); 113 114[DllImport("user32.dll")] 115private static extern uint GetWindowThreadProcessId( 116 IntPtr hWnd, IntPtr ProcessId); 117 118[DllImport("kernel32.dll")] 119private static extern uint GetCurrentThreadId(); 120 121[DllImport("user32.dll")] 122[return: MarshalAs(UnmanagedType.Bool)] 123private static extern bool AttachThreadInput( 124 uint idAttach, uint idAttachTo, bool fAttach); 125 126[DllImport("user32.dll", EntryPoint = "SystemParametersInfo", 127 SetLastError = true)] 128[return: MarshalAs(UnmanagedType.Bool)] 129private static extern bool SystemParametersInfoGet( 130 uint action, uint param, ref uint vparam, uint init); 131 132[DllImport("user32.dll", EntryPoint = "SystemParametersInfo", 133 SetLastError = true)] 134[return: MarshalAs(UnmanagedType.Bool)] 135private static extern bool SystemParametersInfoSet( 136 uint action, uint param, uint vparam, uint init); 137 138private const uint SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000; 139private const uint SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001; 140private const uint SPIF_UPDATEINIFILE = 0x01; 141private const uint SPIF_SENDCHANGE = 0x02; 142"@ 143 144$Win32 = add-type -memberDefinition $cscode -name "Win32ApiFunctions" -passthru 145 146$ps = Get-Process | Where-Object {$_.Name -match "notepad"} 147foreach($process in $ps){ 148$Win32::ActiveWindow($process.MainWindowHandle); 149} 150 151Start-Sleep -s 30 152 153$ps = Get-Process | Where-Object {$_.Name -match "cmd"} 154foreach($process in $ps){ 155$Win32::ActiveWindow($process.MainWindowHandle); 156}

投稿2021/04/01 12:15

Hey_CH

総合スコア437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

empty

2021/04/02 11:20

Hey_CHさん コードを全文載せて頂き、ありがとうございます。 修正したコードと相違はないと思うのですが、全文コピペして実行してみました。 結果は変わらず、コマンドプロンプトやPowershellが表示され、30秒後に閉じられました。 Hey_CHさんと実行環境が違うためかもしれませんね。 検証して確認の上、幾度も回答を頂き、とても嬉しかったです。ありがとうございました。 実行環境の問題なのか、それとも他に方法がないか、あきらめずに挑戦していきます。
Hey_CH

2021/04/02 11:23

お力になれず申し訳ないです。頑張ってくださいー
Hey_CH

2021/04/07 15:16

エディション Windows 10 Pro バージョン 20H2 インストール日 ‎2021/‎01/‎27 OS ビルド 19042.867 エクスペリエンス Windows Feature Experience Pack 120.2212.551.0 僕の環境のOSはこんな感じになっています。(Window7からアップグレードしました) 質問に追記しておくと同じ環境の人が試してくれるかもしれません。 (デスクトップのPCのプロパティを開いて、ちょっとスクロールすると出てくる情報)
empty

2021/04/18 13:37

Hey_CHさん こんばんは。使用環境を教えて頂き、ありがとうございます。 私の使用環境も同じで、Windows7からのアップグレードでWindows10に移行しました。 バージョンも全く同じで、「20H2」でした。 これからも、色々と試行錯誤してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問