【Windows】Bluetoothのリンクキーをスクリプトから取得

少し前にBluetoothキーボードをUbuntuとWindowsで共有する話を書きましたが、何度かペアリングしているうちに両方で登録する手順が面倒に感じてきました。

ペアリング作業だけならともかく、レジストリキーを取得するのは面倒すぎます。

そこで、取得作業をなるべく自動化するべくスクリプトを組むことにしました。

環境

  • Ubuntu 16.04 64bit
  • Windows 10 IP 64bit
  • Microsoft Wedge Mobile Keyboard

リンクキーの取り方

以前もお話ししましたが、Bluetoohで使うリンクキーはレジストリエディタから次のキーから取得できます。

(Pythonで組んだのでバックスラッシュが2つになっています・・・)

HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\services\\BTHPORT\\Parameters\\Keys

また、リンクキーを表示する場合は権限の問題でPSExecというツールからコマンドを発行する必要があります。

そこで、PSExecからregeditをCLIモードで呼び出すべく、次のコマンドを発行しました。

管理者権限でPowerShellを起動して、PSExecがあるディレクトリに移動します。

PS ~\PSTools> .\PsExec.exe -s -i REGEDIT /E D:\temp\test.REG "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys
PS ~\PSTools> cat D:\temp\test.REG
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys]

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys\(BTアダプタのアドレス)]
"(デバイスのMACアドレス)"=hex:(リンクキー)
"(デバイスのMACアドレス)"=hex:(リンクキー)
(略)

のような出力が得られるはずです。

ただ、これだとどのアドレスがどのデバイスに紐づいているかが分からないので、https://macvendors.com/api を使わせてもらってベンダー情報を取得します。

このAPIは、MACアドレスの上位6桁を送信するとベンダーを返してくれるものです。

PS \PSTools> curl "http://api.macvendors.com/7c1e52"


StatusCode        : 200
StatusDescription : OK
Content           : Microsoft
RawContent        : HTTP/1.1 200 OK
                    Access-Control-Allow-Origin: *
                    Content-Length: 9
                    Content-Type: text/plain
                    Date: Tue, 29 Nov 2016 05:41:26 GMT

                    Microsoft
Forms             : {}
Headers           : {[Access-Control-Allow-Origin, *], [Content-Length, 9], [Content-Type, text/plain], [Date, Tue, 29 Nov 2016 05:
                    41:26 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 9

製品情報までは取れませんが、今回はMicrosoftが作っているデバイスが分かればいいので良しとします。

これらを組み合わせてスクリプトを書きます。

スクリプト

PSToolsのディレクトリがスクリプトと同じディレクトリにある状態で実行できます。

#!/usr/bin/env python3.5
# -*- coding:utf-8 -*-

import os
import json
import time
import requests
from subprocess import call

current_dir = os.path.dirname(os.path.abspath(__file__)).replace("/", os.path.sep)


def get_keys():
    cmdfmt = current_dir + '\\PSTools\\PsExec.exe -s -i REGEDIT /E {path} ' \
             '"HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\services\\BTHPORT\\Parameters\\Keys"'
    filename = current_dir + "\\temp.REG"
    cmd = cmdfmt.format(path=filename)
    try:
        call(cmd, shell=True)
        with open(filename, "r") as f:
            reginfo_raw = f.read().replace("\x00", "")
    except Exception as e:
        print(e)
        reginfo_raw = ""
    finally:
        if os.path.exists(filename):
            os.remove(filename)
    reginfo = reginfo_raw.split('"')[1:]
    return [{"macaddr": reginfo[i], "key": reginfo[i+1][5:-2]} for i in range(0, len(reginfo), 2)]


def recv_vendor(macaddr):
    time.sleep(0.5)
    return requests.get("http://api.macvendors.com/" + macaddr[:6]).text

if __name__ == "__main__":
    keys = get_keys()
    for key in keys:
        key.update({"vendor": recv_vendor(key["macaddr"])})
    print(json.dumps(keys, indent=4, separators=(',', ': ')))

ポイントはPsExecの出力ファイルがUnicode形式だったので、f.read()する時にreplace(“\x00”, “”)しているあたりですかね。。

もっと行儀のよい方法があったら教えていただけるとありがたいです。

これを実行すると、

PS \regshow> python .\regedit.py

PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com


REGEDIT exited on SAKAKI-MOBILE with error code 0.
[
(略)
    {
        "macaddr": "(デバイスのMACアドレス)",
        "key": "(リンクキー)",
        "vendor": "Microsoft"
    }
]

いい感じに自動化できました。

これからはじゃんじゃんOS間でペアリングしていきますよ!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です