Python(pywin32) + WMI でレジストリを読む


# 概要

Python(pywin32)で[Windows Management Instrumentation(WMI)][wmi]を使ってレジストリの情報を取得します。

次回、コードで利用しているオブジェクトの説明(もう少し具体的なクラス図かシーケンス図か)を入れる予定。

## 注

ネットにPython(pywin32) + WMIの情報が少なく、嵌りも多いので、**普通に使うにはなかなかおすすめできない** です。現時点では。

- Python標準の[winreg][winreg]を使う([サンプルコード][winreg_sample])
- レジストリを[reg.exe][regexe]でやってテキスト処理に持ち込む([サンプルコード](https://qiita.com/int_main_void/items/d2099e7f349cdb3aa001#%E3%83%AC%E3%82%B8%E3%82%B9%E3%83%88%E3%83%AA%E3%82%92regexe%E3%81%A7%E3%82%84%E3%81%A3%E3%81%A6%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E5%87%A6%E7%90%86%E3%81%AB%E6%8C%81%E3%81%A1%E8%BE%BC%E3%82%80))
- (WMIをやるにしても、) wmiモジュール使う([サンプルコード][wmi_mod])

とか他の方法をおすすめします。

# レジストリについて

レジストリの概要は以下の記事がまとまっています。
※レジストリハイブはデフォルトだと見えないファイルです。[参考][show_sys_file]

- [第5回システム設定を集中管理するレジストリ：Windows OS入門 - ＠IT][reg_basics]
    - キーワード：ルートキー、サブキー、レジストリハイブ、値(名前、型、データ)

以下は必要に応じてどうぞ。

- [第6回レジストリのリダイレクトと仮想化およびレジストリ操作ツール：Windows OS入門 - ＠IT][registry_redirect_reflect]
    - キーワード：32bit/64bitの違い、リダイレクト、リフレクション(廃止)、仮想化
- [Inside the Registry - technet.microsoft.com][inside_reg]
    - キーワード：Hive Structure, Volatile hive, Stable Storage
- [Where are the Windows registry files located in Windows 10_8_7-The Windows Club][twc]
    - キーワード：Volatile hive, hivelist

# WMIについて

全体像を把握するのは以下の記事がいいです。
※ 特に、「WMIアーキテクチャ」の図の周辺

- [WMIアーキテクチャ-＠IT](http://www.atmarkit.co.jp/fwin2k/insiderseye/20030527beyond_gui/beyond_gui_01.html#WMI)

↑を読んだあと、↓を掻い摘んでよむのがいいかと。
[WMI Scripting Primer  Part 1   Microsoft Docs][wmi_primer]
[WMI Providers Microsoft Docs][wmi_provider]
[Scripting API Objects Microsoft Docs][wmi_objs]


# コード

##値を取得する

HKEY_CURRENT_USER\Software\7-ZipのPath64の値のデータを取得します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/34777/e39ba403-6b81-5861-61d9-5fab0f1e0c23.png)


```python
# -*- coding: utf-8 -*-
import win32com.client

HKEY_CLASSES_ROOT = 2147483648
HKEY_CURRENT_USER = 2147483649
HKEY_LOCAL_MACHINE = 2147483650
HKEY_USERS = 2147483651
HKEY_CURRENT_CONFIG = 2147483653

SWbemLocator=win32com.client.Dispatch(r"WbemScripting.SWbemLocator")
SWbemServices=SWbemLocator.ConnectServer(".", r"root\default")
StdRegProv=SWbemServices.Get("StdRegProv")
in_param=StdRegProv.Methods_("GetStringValue").InParameters.SpawnInstance_()
in_param.hDefKey=HKEY_CURRENT_USER
in_param.sSubKeyName = r"SOFTWARE\7-Zip"
in_param.sValueName = "Path64"
ret=SWbemServices.ExecMethod("StdRegProv", "GetStringValue", in_param)

print(ret.GetObjectText_())
print(ret.sValue)
```

###出力

```python
instance of __PARAMETERS
{
        ReturnValue = 0;
        sValue = "C:\\Program Files\\7-Zip\\";
};

C:\Program Files\7-Zip\
```

##値の名前と型を列挙する

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorerの値の名前と種類(型)を列挙します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/34777/bf71ecc3-be07-9704-a7b0-b13f6f91c3d1.png)



```python
# -*- coding: utf-8 -*-
import win32com.client

HKEY_CLASSES_ROOT = 2147483648
HKEY_CURRENT_USER = 2147483649
HKEY_LOCAL_MACHINE = 2147483650
HKEY_USERS = 2147483651
HKEY_CURRENT_CONFIG = 2147483653

import win32com.client
SWbemLocator=win32com.client.Dispatch(r"WbemScripting.SWbemLocator")
SWbemServices=SWbemLocator.ConnectServer(".", r"root\default")
StdRegProv=SWbemServices.Get("StdRegProv")
in_param=StdRegProv.Methods_("EnumValues").InParameters.SpawnInstance_()
in_param.hDefKey=HKEY_CURRENT_USER
in_param.sSubKeyName = r"Software\Microsoft\Windows\CurrentVersion\Explorer"
SWbemObject=SWbemServices.ExecMethod("StdRegProv", "EnumValues", in_param)
print(SWbemObject.GetObjectText_())

# EnumValues method of the StdRegProv class
# https://msdn.microsoft.com/en-us/library/aa390388
# Types [out]参照

reg_types= {
    "REG_SZ":1,
    "REG_EXPAND_SZ":2,
    "REG_BINARY":3,
    "REG_DWORD":4,
    "REG_MULTI_SZ":7,
    "REG_QWORD":11
}

print("値の名前:値の型")
for n,t in zip(SWbemObject.sNames, SWbemObject.Types):
    print(f"{n}:{list(reg_types.keys())[list(reg_types.values()).index(t)]}")
```


###出力

```python
instance of __PARAMETERS
{
        ReturnValue = 0;
        sNames = {"ShellState", "ExplorerStartupTraceRecorded", "UserSignedIn", "SlowContextMenuEntries", "TelemetrySalt", "SIDUpdatedOnLibraries", "LocalKnownFoldersMigrated", "GlobalAssocChangedCounter", "FirstRunTelemetryComplete", "AppReadinessLogonComplete", "EdgeDesktopShortcutCreated", "PostAppInstallTasksCompleted", "link"};
        Types = {3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3};
};

値の名前:値の型
ShellState:REG_BINARY
ExplorerStartupTraceRecorded:REG_DWORD
UserSignedIn:REG_DWORD
SlowContextMenuEntries:REG_BINARY
TelemetrySalt:REG_DWORD
SIDUpdatedOnLibraries:REG_DWORD
LocalKnownFoldersMigrated:REG_DWORD
GlobalAssocChangedCounter:REG_DWORD
FirstRunTelemetryComplete:REG_DWORD
AppReadinessLogonComplete:REG_DWORD
EdgeDesktopShortcutCreated:REG_DWORD
PostAppInstallTasksCompleted:REG_DWORD
link:REG_BINARY
```

##値の名前、型、データを列挙する

データも合わせてとってきてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/34777/60252634-3b04-f965-192b-ccb164a0809b.png)


```python
# -*- coding: utf-8 -*-
HKEY_CLASSES_ROOT = 2147483648
HKEY_CURRENT_USER = 2147483649
HKEY_LOCAL_MACHINE = 2147483650
HKEY_USERS = 2147483651
HKEY_CURRENT_CONFIG = 2147483653

import win32com.client
SWbemLocator=win32com.client.Dispatch(r"WbemScripting.SWbemLocator")
SWbemServices=SWbemLocator.ConnectServer(".", r"root\default")
StdRegProv=SWbemServices.Get("StdRegProv")
in_param=StdRegProv.Methods_("EnumValues").InParameters.SpawnInstance_()
in_param.hDefKey=HKEY_CURRENT_USER
in_param.sSubKeyName = r"Software\Microsoft\Windows\CurrentVersion\Explorer"
EnumValues_SWbemObject=SWbemServices.ExecMethod("StdRegProv", "EnumValues", in_param)

# EnumValues method of the StdRegProv class
# https://msdn.microsoft.com/en-us/library/aa390388
# Types [out]参照

reg_types= {
    "REG_SZ":1,
    "REG_EXPAND_SZ":2,
    "REG_BINARY":3,
    "REG_DWORD":4,
    "REG_MULTI_SZ":7,
    "REG_QWORD":11
}

# 値の名前、型からデータを取得して文字列で返す
def get_value_data_str(value_name,value_type, StdRegProv):
    if value_type == "REG_BINARY":
        method = "GetBinaryValue"
    elif value_type == "REG_DWORD":
        method = "GetDWORDValue"
    else:
        return "None"

    in_param=StdRegProv.Methods_(method).InParameters.SpawnInstance_()
    in_param.hDefKey=HKEY_CURRENT_USER
    in_param.sSubKeyName = r"Software\Microsoft\Windows\CurrentVersion\Explorer"
    in_param.sValueName = value_name
    SWbemObject=SWbemServices.ExecMethod("StdRegProv", method, in_param)

    if value_type == "REG_BINARY":
        return " ".join(map(lambda v:format(v, '02x'), SWbemObject.uValue))
    else:
        return "0x"+format(SWbemObject.uValue, '08x')

print("値の名前:値の型:値のデータ")
for ValueName,ValueType in zip(EnumValues_SWbemObject.sNames, EnumValues_SWbemObject.Types):
    ValueTypeStr = list(reg_types.keys())[list(reg_types.values()).index(ValueType)]
    print(f"{ValueName}:{ValueTypeStr}:{get_value_data_str(ValueName,ValueTypeStr,StdRegProv)}")

```

### 出力

```python
値の名前:値の型:値のデータ
ShellState:REG_BINARY:24 00 00 00 34 28 00 00 略
ExplorerStartupTraceRecorded:REG_DWORD:0x00000001
UserSignedIn:REG_DWORD:0x00000001
SlowContextMenuEntries:REG_BINARY:4f 54 ec 56 00 略
TelemetrySalt:REG_DWORD:0x00000006
SIDUpdatedOnLibraries:REG_DWORD:0x00000001
LocalKnownFoldersMigrated:REG_DWORD:0x00000001
GlobalAssocChangedCounter:REG_DWORD:0x00000058
FirstRunTelemetryComplete:REG_DWORD:0x00000001
AppReadinessLogonComplete:REG_DWORD:0x00000001
EdgeDesktopShortcutCreated:REG_DWORD:0x00000001
PostAppInstallTasksCompleted:REG_DWORD:0x00000001
link:REG_BINARY:16 00 00 00
```

# 備考
## レジストリをreg.exeでやってテキスト処理に持ち込む

HKEY_LOCAL_MACHINE\Software\Classesのキーを列挙する場合・・・

```python
In [251]: reg_query=subprocess.run(["reg", "query", r"HKEY_LOCAL_MACHINE\Software\Classes"], stdout=subprocess.PIPE)

In [252]: for s in reg_query.stdout.decode('cp932').split():
     ...:     m=re.search(r".*Excel.Application$",s)
     ...:     if m:
     ...:         print(m.group())
HKEY_LOCAL_MACHINE\Software\Classes\Excel.Application
```



# 参考

- [WMI Scripting Primer  Part 1   Microsoft Docs][wmi_primer]
- [WMI Providers - Microsoft Docs][wmi_provider]
- [StdRegProv class][StdRegProv_class]
- [Scripting API Objects Microsoft Docs][wmi_objs]
- [WMI Step - WMI Fun!!][wmi_step]
- [WMI Library - WMI Fun!!][wmilib]
- [Insider's Eye：GUIを超えて進化するWindows管理ツール（1）- ＠IT][wmi_arci]
- [WMI - マイクロソフト系技術情報 Wiki][wmi_mswiki]
- [JScriptでWMI（その１） - Qiita][jscript_wmi_qiita]
- [WshShell オブジェクト - msdn][wshshell]
- [jscriptから WMIを使ってレジストリキー_値列挙 - あぁ そうだった][jscript-wmi]
- [Windows Management Instrumentation - Microsoft Docs][wmi]
- [winreg でレジストリを読み書きするサンプルコード - かせきのうさぎさん][winreg_sample]
- [2. システムファイルを表示する方法 - 121ware.com][show_sys_file]
- [第5回 システム設定を集中管理するレジストリ：Windows OS入門 - ＠IT][reg_basics]
- [Where are the Windows registry files located in Windows 10_8_7-The Windows Club][twc]
- [Inside the Registry - technet.microsoft.com][inside_reg]
- [PythonからリモートPCの色んな情報を抜いてみた by WMI Library - Qiita][wmi_mod]



[wmi_mod]:(https://qiita.com/nagase/items/3e9947afbf09063906dc
[wmi_objs]:https://docs.microsoft.com/en-us/windows/desktop/wmisdk/scripting-api-objects
[StdRegProv_class]:https://msdn.microsoft.com/en-us/library/aa393664
[wmi_provider]:https://docs.microsoft.com/en-us/windows/desktop/wmisdk/wmi-providers
[wmi_primer]:https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/ms974579(v=msdn.10)#wmi-architecture
[wmi_step]:http://www.wmifun.net/step/
[wmilib]:http://www.wmifun.net/library/
[wmi_arci]:http://www.atmarkit.co.jp/fwin2k/insiderseye/20030527beyond_gui/beyond_gui_01.html
[jscript_wmi_qiita]:https://qiita.com/tnakagawa/items/ae579f19d74dd86e40c6#%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E4%B8%80%E8%A6%A7%E5%8F%96%E5%BE%97
[wmi_mswiki]:https://techinfoofmicrosofttech.osscons.jp/index.php?WMI
[registry_redirect_reflect]:http://www.atmarkit.co.jp/ait/articles/1502/19/news120.html
[moriya.xrea.jp_regexe]:https://moriya.xrea.jp/tdiary/20150515.html
[qiita_win_reg]:https://qiita.com/hotta/items/9e28ff11bdd60cae6b21
[twc]:https://www.thewindowsclub.com/where-are-the-windows-registry-files-located-in-windows-7
[inside_reg]:https://technet.microsoft.com/en-in/library/cc750583(en-us).aspx
[wow64_reg]:https://ja.wikipedia.org/wiki/WOW64#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%A8%E3%83%AC%E3%82%B8%E3%82%B9%E3%83%88%E3%83%AA
[show_sys_file]:https://121ware.com/qasearch/1007/app/servlet/qadoc?QID=018261#a02

[powershell_reg]:http://www.sakutyuu.com/technology/?p=134#i-4
[winreg]:https://docs.python.jp/3/library/winreg.html
[winreg_sample]:http://itasuke.hatenablog.com/entry/2018/01/08/133510

[regexe]:http://www.atmarkit.co.jp/ait/articles/0402/21/news005.html
[reg_basics]:http://www.atmarkit.co.jp/ait/articles/1501/22/news143.html

[wmi]:https://docs.microsoft.com/en-us/windows/desktop/wmisdk/wmi-start-page
[wshshell]:https://msdn.microsoft.com/ja-jp/library/cc364436.aspx
[jscript-wmi]:https://passing.breeze.cc/mt/archives/2009/07/jscript-wmi.html