いろいろとあって、PowershellでJoy-Conの接続状態を取得したかったのですがかなり苦労したので備忘録を残しておきます。
全体のソースは一番下に載せておきます。
はじめに
Nintendo Switchに付属しているコントローラである、Joy-ConはPCとBluetoothで接続することが可能です。
ご存じの通り、Bluetooth製品はまず「ペアリング」を行い、その後「接続」され始めて使用が可能となります。
Joy-Conがペアリングされていて接続されていない状態なのか、それとも既に接続されている状態なのかを取得したかったのですが、Get-PnpDevice
からはその状態を判別できなかったため、Get-PnpDeviceProperty
を使って詳しいプロパティから状態を取得しました。
実践
ここからは全体のソースを小分けにして何をしているか説明します。
1.登録されているJoy-Con一覧を取得
とりあえず、"Joy-Con"として登録されているデバイス一覧を取得します。
ここではペアリングされているデバイスのみが取得可能なので、ここで取得できていればペアリングされているということになります。
# 1.登録されているJoy-Con一覧を取得
$joyconInfo = Get-PnpDevice | ? {$_.friendlyname -like '*Joy-Con*'}
2.登録されているJoy-Conの中で接続されているものがあるか判定
ここでは1で取得したデバイス一覧からそれぞれの詳しい情報を取得して判定していきます。
Get-PnpDeviceProperty
で取得した結果は以下のようなものが返却されています。
InstanceId KeyName Type Data
---------- ------- ---- ----
BTHENUM... DEVPKEY_Device_DeviceDesc String Bluetooth デバイス
BTHENUM... DEVPKEY_Device_HardwareIds StringList {hogee}
BTHENUM... DEVPKEY_Device_CompatibleIds StringList {hoge}
BTHENUM... DEVPKEY_Device_Class String Bluetooth
BTHENUM... DEVPKEY_Device_ClassGuid Guid {hoge}
BTHENUM... DEVPKEY_Device_Driver String {hoge}hoge
BTHENUM... DEVPKEY_Device_ConfigFlags UInt32 0
BTHENUM... DEVPKEY_Device_Manufacturer String Microsoft
BTHENUM... DEVPKEY_Device_FriendlyName String Joy-Con (L)
BTHENUM... DEVPKEY_Device_PDOName String \Device\hoge
BTHENUM... DEVPKEY_Device_Capabilities UInt32 000
BTHENUM... DEVPKEY_Device_EnumeratorName String hoge
---- ---- (後略) ---- ----
この中で使用するのはKeyNameがDEVPKEY_Device_IsPresent
とDEVPKEY_Bluetooth_LastConnectedTime
の値になります。
これらのプロパティから以下のことがわかります。
-
DEVPKEY_Device_IsPresent
がFalseの時はPC側のBluetooth自体がOFFとなっている。 -
DEVPKEY_Bluetooth_LastConnectedTime
がプロパティにある場合、ペアリングされているかつデバイスが接続されていない状態。
(以上2つは実際の値から推測したもののため正しくない場合があります。)
上記の判定を取得したデバイスごとに実施し、どちらの条件にもかからないデバイスがあった場合に$hasValidJoyCon
をTrueとして、有効なデバイスがあったことをロジック3に伝えます。
# 2.登録されているJoy-Conの中で接続されているものがあるか判定
#有効なJoyConがあるか
$hasValidJoyCon = $False
#bluetoothが無効となっている
$bluetoothDisable = $False
#JoyConが接続されていない
$joyConNotConnected = $False
#デバイスリストを回す
foreach($aInstance in $joyconInfo){
$joyconProperties = Get-PnpDeviceProperty -InstanceId $aInstance.InstanceId
$bluetoothDisable = $False
$joyConNotConnected = $False
foreach($aProperty in $joyconProperties){
if($aProperty.KeyName -eq "DEVPKEY_Device_IsPresent"){
if($aProperty.Data -eq $False){
# Bluetoothが有効か?
$bluetoothDisable = $True
}
}
if($aProperty.KeyName -eq "DEVPKEY_Bluetooth_LastConnectedTime"){
# 最終接続日時(これがプロパティに入っている場合、Bluetoothが有効かつ、デバイスが接続されていない)
$joyConNotConnected = $True
}
}
IF(!$bluetoothDisable -And !$joyConNotConnected){
$hasValidJoyCon = $True
break
}
}
3.接続されているものがなければ、処理を終了
ここは単に結果を出力しているだけですが、1件でも有効なデバイスがあれば素通り、無効なデバイスのみであれば最後の1件の理由がわかるようになっています。
本来なら取得できたデバイスすべての結果を出力するべきかもしれませんが、自分用ツールなので。。。
# 3.接続されているものがなければ、処理を終了
IF(!$hasValidJoyCon){
IF($bluetoothDisable){
echo "Bluetoothが無効なので処理を終了します。設定でBluetoothが有効になっていることを確認してください。"
}
ELSEIF($joyConNotConnected){
echo "Joyconが接続されていないので処理を終了します。設定でJoyconが接続されていることを確認してください。"
}
exit 1
}
おわり
本記事は以上となります。
PowershellでBluetoothデバイスの状態を取得する需要があるかは疑問ですが、私が調べた限りではやっている方がいなかったので備忘録として残しておきます。
なにかおかしい部分などあればコメント等よろしくお願いします。
ソース全体
echo 'Joycon起動処理を実行しています…'
# 1.登録されているJoy-Con一覧を取得
$joyconInfo = Get-PnpDevice | ? {$_.friendlyname -like '*Joy-Con*'}
# 2.登録されているJoy-Conの中で接続されているものがあるか判定
#有効なJoyConがあるか
$hasValidJoyCon = $False
#bluetoothが無効となっている
$bluetoothDisable = $False
#JoyConが接続されていない
$joyConNotConnected = $False
foreach($aInstance in $joyconInfo){
$joyconProperties = Get-PnpDeviceProperty -InstanceId $aInstance.InstanceId
$bluetoothDisable = $False
$joyConNotConnected = $False
foreach($aProperty in $joyconProperties){
if($aProperty.KeyName -eq "DEVPKEY_Device_IsPresent"){
if($aProperty.Data -eq $False){
# Bluetoothが有効か?
$bluetoothDisable = $True
}
}
if($aProperty.KeyName -eq "DEVPKEY_Bluetooth_LastConnectedTime"){
# 最終接続日時(これがプロパティに入っている場合、Bluetoothが有効かつ、デバイスが接続されていない)
$joyConNotConnected = $True
}
}
IF(!$bluetoothDisable -And !$joyConNotConnected){
$hasValidJoyCon = $True
break
}
}
# 3.接続されているものがなければ、処理を終了
IF(!$hasValidJoyCon){
IF($bluetoothDisable){
echo "Bluetoothが無効なので処理を終了します。設定でBluetoothが有効になっていることを確認してください。"
}
ELSEIF($joyConNotConnected){
echo "Joyconが接続されていないので処理を終了します。設定でJoyconが接続されていることを確認してください。"
}
exit 1
}
echo "Joyconが接続されています"