とりあえずソース
丸コピして保存すればすぐ使えるはず。
試しに3つほどAPIを定義しているが、使いたいAPIがほかにあればMSDNのサイト等から検索して拡張する。
Win32API.ps1
$Win32 = &{
# ========= C#言語によるWin32Api関数定義(ここから) =========
$cscode = @"
[DllImport("user32.dll")]
public static extern int MessageBox(
IntPtr hWnd, // オーナーウィンドウのハンドル
string lpText, // メッセージボックス内のテキスト
string lpCaption, // メッセージボックスのタイトル
UInt32 uType // メッセージボックスのスタイル
);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(
string lpClassName, // クラス名
string lpWindowName // ウィンドウ名
);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(
IntPtr hWnd, // ウィンドウのハンドル
IntPtr hWndInsertAfter, // 配置順序のハンドル
int X, // 横方向の位置
int Y, // 縦方向の位置
int cx, // 幅
int cy, // 高さ
UInt32 uFlags // ウィンドウ位置のオプション
);
// 拡張版FindWindow定義 (@mima_ita様 考案)
public static IntPtr FindWindowByName(string lpWindowName) {
return FindWindow(null, lpWindowName);
}
"@
# ========= C#言語によるWin32Api関数定義(ここまで) =========
return (add-type -memberDefinition $cscode -name "Win32ApiFunctions" -passthru)
}
前提条件:
PowerShell 2.0以上(Windows7以降であれば問題ないはず)
使い方:
メッセージボックス表示、およびFindWindowを利用する例
Test.ps1
# Win32API関数をロード
. ".\Win32API.ps1"
# メッセージボックス表示
$Win32::MessageBox(0, "Hello, World!", "Test", 0)
# 標準出力にFindWindowの結果表示
$Win32::FindWindowByName("ウィンドウタイトル")
備考:
FindWindowに関しては思ったように動かないことが多いので、以下のようなプログラムで取得した方がベターかもしれない。
# 筆者の環境では、第一引数・第二引数ともに有効な文字列を入力しないとうまく取ってこれなかった。
# (何か見落としてるだけかもしれないが)
# プロセス一覧を取得
$psArray=[System.Diagnostics.Process]::GetProcesses()
foreach ($ps in $psArray) {
# Windowハンドル取得
$hWnd = $ps.MainWindowHandle
# 何か処理
...
}
2022/09/12 追記:
うまく動かない原因はpowershellとC#間のキャストの箇所で、第一引数をnull決め打ちすると回避できる模様。
記事内の拡張版関数(FindWindowByName)を利用すれば、問題なく動作するようです。筆者の環境でも値がとれていることは確認済。
↓↓↓ 詳細は @mima_ita 様のコメントを参照 ↓↓↓
コメント欄リンク