Windows 再生デバイスの切り替え[PowerShell]AIでつくってみた

 ## Windows 再生デバイス/サウンドの切り替え[PowerShell]
簡単に切り替えを、出来るようにする。
複数あるサウンド再生デバイスを、ラジオボタンで選べる。

めんどくさいのでAIで作ってみた。
すでに自分で作成したのがあったが、IDが変わったりすることで、
うまくいかないこともあり、その度に修正するのも億劫なので
AIで作成してみたら、簡単にできました。
(ほぼ手を入れていないので、OKボタンの位置が...)


![スクリーンショット 2024-11-17 015222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615816/6773aa0b-ca85-8af5-63bb-ca1066c38f94.png)


下記スクリプト(kirikae.ps1)を保存。それをショートカットで登録してください。
"C:\path\script\kirikae.ps1"は実際のスクリプトのパスに置き換え

``` ショートカット例
powershell.exe -WindowStyle Hidden -ExecutionPolicy RemoteSigned -File "C:\path\script\kirikae.ps1"
```

``` kirikae.ps1
# AudioDeviceCmdletsモジュールのインポートまたはインストール
if (!(Get-Module -ListAvailable -Name AudioDeviceCmdlets)) {
    Install-Module -Name AudioDeviceCmdlets -Scope CurrentUser
}
Import-Module AudioDeviceCmdlets

# 再生デバイスのリストを取得する
$playbackDevices = Get-AudioDevice -List | Where-Object { $_.Type -eq "Playback" }

# 再生デバイス情報の配列を作成する
$deviceList = @()

foreach ($device in $playbackDevices) {
    $deviceInfo = [PSCustomObject]@{
        ID      = $device.ID
        Name    = $device.Name
        Default = $device.Default
    }
    $deviceList += $deviceInfo
}

Add-Type -AssemblyName System.Windows.Forms
# フォーム作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "サウンド切り替え"
$form.StartPosition = "CenterScreen"

$font = New-Object System.Drawing.Font("Arial", 10)

# 動的にラジオボタン作成
$top = 20
foreach ($radio in $deviceList) {
    $radioButton = New-Object System.Windows.Forms.RadioButton
    $radioButton.Text = $radio.Name
    $radioButton.Name = $radio.ID.ToString()
    $radioButton.Font = $font
    $radioButton.Checked = $radio.Default
    $radioButton.AutoSize = $true
    $radioButton.Top = $top
    $radioButton.Left = 20
    $form.Controls.Add($radioButton)
    $top += 30
}

# OK ボタン
$okButton = New-Object System.Windows.Forms.Button
$okButton.Text = "OK"
$okButton.Top = $top + 10
$okButton.Left = 20
$okButton.Add_Click({
    foreach ($control in $form.Controls) {
        if ($control.Checked) {
            Set-AudioDevice -ID $control.Name
#            [System.Windows.Forms.MessageBox]::Show("Selected Option: $($control.Name)")
        }
    }
    $form.Close()
})
$form.Controls.Add($okButton)

# キャンセルボタン
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Text = "Cancel"
$cancelButton.Top = $top + 10
$cancelButton.Left = 100
$cancelButton.Add_Click({
    $form.Close()
})
$form.Controls.Add($cancelButton)

# フォームのサイズを動的に設定
$form.Height = $top + 80
$form.Width = 300

# フォーム表示
$form.ShowDialog()

```
## AIでつくってみた
Microsoft Copilotに、聞いてみたら簡単にできました。
作成例としての覚書
 1. powershellでサウンドの再生デバイスのリストの取得 
 2. powershellでフォーム ラジオボタン

上記の内容を個別に聞いて、スクリプトを作成。
まとめて聞くとうまくいかないので..
2つを合わせて、数行の追加・修正で対応
#スクリプトのOKを押したらのところに～ サウンド切り替えのコードを追加
#配列の名前を修正、要らない配列は削除など
的確に仕様を入れると、ほぼ無修正で済みます。

```1.powershellでサウンドの再生デバイスのリストの取得 
powershellでサウンドの再生デバイスのリストの取得
AudioDeviceCmdlets モジュールを使用する
playbackデバイスのみ
配列にID,Name,Default(デバイスのDefault)を入れる
```
```2. powershellでフォーム ラジオボタン
powershellでフォーム
複数のラジオボタンを表示
配列にID,Name,Defaultが入っている
配列の数でラジオボタン表示
--
ラジオボタンのテキストにName
ラジオボタンのテキストの長さは可変
ラジオボタンのNameにID
ラジオボタンのチェックにDefault
フォントの設定も入れる
--
フォーム下部にOKとキャンセルボタン
ラジオボタンの数によりフォームのサイズも変わる
OKを押したら、選択されているラジオボタンを表示

```
#### ※同じようにAIに聞いても、期待できる結果と違うこともありますので注意。
例えば ラジオボタンをグループ化したりするコードを返したり
サウンドのリストをWindows APIを使用するのだったり
適確に指示すれば、回避もできますが、どれが正解かは自分で判断しないといけない。
こちらが何回か質問していることにより、学習して回避するコードにもなってたりもしています。
例えば、フォーム・コントロールの作成時に入れる数値は、一旦変数に入れて計算するとか
四則演算を括弧の中で行うと実行時にエラー表示になるので(form.xxx($a +50, $i *3 +50))等
(単純に、フォーム・コントロールの作成時に入れる数値は括弧の中で計算しないでとか）
それ以降、変数で計算してから代入するコードに変わりましたが...
実際は、この記事を書く前に、作成したスクリプトと、記事を書くので再作成しスクリプトは、かなり違っています。
後から作成したスクリプトの方が、一旦変数で計算してから代入するコード自体が少なくなっています。
プロパティ(xxx,yyy)みたいに複数に入れるのが、プロパティ.A=xxx プロパティ.B=yyy 単独で入れるコードに変更されています。
良くはなっていますが、結果が毎回違うと記事とかにすると あれれ? とかなります。
## AIでコメントを作成（辞め時が難しい）
スクリプトのコメントがあれなので、AIに作ってもらった。
作り方のコツ
* コードを要約させる。
* 機能について説明をつけてもらう。
* 既存の、コメントはいったん削除
* 長文も可能もOKとか
* おしゃれに 中二病風に お嬢様がセバスチャンに頼む風とかで  コメントを作成
* .etc .etc
* 聞くAIによって、得意不得意あり。お好みのAIを探そう🕵️

上記なことをAIに入れれば、殺伐としたコードが...
こんなのが出来ます。

例）UTF-8 BOM付きで保存(そうしないとエラーで動かないので注意）
```
# ==========================
# 🎧 サウンドデバイス・マジシャン 🎚️
# ==========================
#
# このスクリプトは、退屈な音声デバイス切り替えを魔法のような操作に変える、
# PowerShellの究極のオーディオ変換ツール！
#
# 特徴:
# - 🔍 全てのサウンドデバイスを自動検出
# - 🖱️ 直感的なGUIインターフェース
# - 🎯 シンプルで効率的なデバイス切り替え
#
# 作者: 音響エンジニアリングの錬金術師
# バージョン: 1.0.0
# 最終更新日: 2024年

# -----------------------
# モジュールのインストール魔法 ✨
# -----------------------
# システムに必要な「音響変換」の呪文（モジュール）が存在しない場合、
# 自動的に召喚（インストール）します！
if (!(Get-Module -ListAvailable -Name AudioDeviceCmdlets)) {
    # カレントユーザーの魔法の領域にモジュールをインストール
    Install-Module -Name AudioDeviceCmdlets -Scope CurrentUser
}
# モジュールを現在の魔法のセッションに読み込む
Import-Module AudioDeviceCmdlets

Add-Type -AssemblyName System.Windows.Forms

# -----------------------
# 🧙‍♂️ Windowsフォームの魔法の杖を展開 🪄
# -----------------------
# インターフェースを生み出すための、隠されたAPIの力を解放！
$form = New-Object System.Windows.Forms.Form

# -----------------------
# 🔊 音響の秘密の地図を作成 🗺️
# -----------------------
# システム内に隠された全ての音声出力デバイスを探索
$playbackDevices = Get-AudioDevice -List | Where-Object { $_.Type -eq "Playback" }
# タイプ「Playback」のデバイスのみを捕獲 - まるでポケモンGO!
$deviceList = @()
foreach ($device in $playbackDevices) {
    # 🧩 デバイス情報を精密に組み立てる
    # それぞれのデバイスの遺伝子（DNA）を解析し、構造化された情報オブジェクトに変換
    $deviceInfo = [PSCustomObject]@{
        Index   = $device.Index       # デバイスの生体認証インデックス
        ID      = $device.ID          # 音響世界のパスポート
        Name    = $device.Name        # デバイスの華麗なるステージネーム
        Default = $device.Default     # 現在の王座（デフォルト）の占有状況
    }
    $deviceList += $deviceInfo
}

# -----------------------
# 🎲 デバイスの数を数える - ラジオボタンの軍団を準備！
# -----------------------
$form.Text = "サウンド切り替えの儀式"  # 儀式のタイトル
$form.StartPosition = "CenterScreen"     # 魔法の円の中心に召喚
$font = New-Object System.Drawing.Font("Arial", 10)  # 文字のエネルギーを設定

# -----------------------
# 📻 ラジオボタンの生成関数 - デバイスを視覚化する錬金術
# -----------------------
$top = 20
foreach ($radio in $deviceList) {
    $radioButton = New-Object System.Windows.Forms.RadioButton
    $radioButton.Text = $radio.Name        # デバイスの真の名前を明かす
    $radioButton.Name = $radio.ID.ToString() # 秘密の識別コード
    $radioButton.Font = $font
    $radioButton.Checked = $radio.Default   # デフォルトの王座の継承者を自動選択
    $radioButton.AutoSize = $true
    $radioButton.Top = $top
    $radioButton.Left = 20
    $form.Controls.Add($radioButton)
    $top += 30  # 次の次元の入口への距離
}

# -----------------------
# 🕹️ ユーザーとの相互作用のポータルを開く
# -----------------------
# OKボタン - 次元の扉を開く🌀
$okButton = New-Object System.Windows.Forms.Button
$okButton.Text = "OK"
$okButton.Top = $top + 10
$okButton.Left = 20
$okButton.Add_Click({
    # 選択の確定 - 音響次元の転移スイッチ
    foreach ($control in $form.Controls) {
        if ($control.Checked) {
            # 現在活性化している次元の入口を特定
            Set-AudioDevice -ID $control.Name
        }
    }
    $form.Close()  # ポータルを閉じる
})
$form.Controls.Add($okButton)

# キャンセルボタン - 冒険の中断🚫
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Text = "Cancel"
$cancelButton.Top = $top + 10
$cancelButton.Left = 100
$cancelButton.Add_Click({
    $form.Close()  # ポータルを閉じる
})
$form.Controls.Add($cancelButton)

# -----------------------
# フォームのサイズを魔法のように調整 ✨
# -----------------------
$form.Height = $top + 80  # 錬金術の儀式で高さを決定
$form.Width = 300         # 幅を華麗に設定

# -----------------------
# 🚪 相互作用のポータルを開く
# -----------------------
$form.ShowDialog()
# 🌈 最終的な次元の入り口を開き、ユーザーの選択を待機
# 🎊 音響の旅、終了！お疲れ様でした！ 👾

```