16
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

powershellでWin32 APIを利用する(powershell 2.0以上)

Last updated at Posted at 2017-09-04

とりあえずソース

 丸コピして保存すればすぐ使えるはず。
 試しに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 様のコメントを参照 ↓↓↓
コメント欄リンク

参考文献

 LoadWithPartialNameをやめてAdd-Typeコマンドレットへ

 Powershell > スクリプトを複数ファイルで実装する方法 > .(ドット)で別スクリプトを読込む

16
21
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?