Python、WMI、注册表和奇怪的结果

标签 python windows registry wmi pywin32

我需要创建一个Python脚本来遍历HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall的内容并返回每个键的DisplayName

我使用它作为起点(在另一个堆栈溢出帖子中找到)

import _winreg
import wmi

c = wmi.WMI(namespace="default").StdRegProv

result, value = c.GetStringValue (
    hDefKey=_winreg.HKEY_LOCAL_MACHINE,
    sSubKeyName="SYSTEM\ControlSet001\Services\MRxDAV",
    sValueName="ImagePath"
)
print value

这有效。它返回:

\SystemRoot\system32\drivers\mrxdav.sys

但是,如果我更改 sSubKeyNamesValueName(为有效值),它看起来会非常不稳定,更频繁地返回 None比不。

例如:

c = wmi.WMI(namespace="default").StdRegProv

result, value = c.GetStringValue (
    hDefKey=_winreg.HKEY_LOCAL_MACHINE,
    sSubKeyName="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E5D76AD-A3FB-48D5-8400-8903B10317D3}",
    sValueName="DisplayName"
)
print value

这会导致打印None

但是,

result, value = c.GetStringValue (
    hDefKey=_winreg.HKEY_LOCAL_MACHINE,
    sSubKeyName="SOFTWARE\Microsoft\Windows\CurrentVersion\Installer",
    sValueName="InstallerLocation"
)
print value

返回正确的值,

C:\Windows\SysWOW64\

如果我们尝试:

result, value = c.GetStringValue (
    hDefKey=_winreg.HKEY_LOCAL_MACHINE,
    sSubKeyName="SOFTWARE\Microsoft\Windows\CurrentVersion\OptimalLayout",
    sValueName="LayoutFilePath"
)
print value

返回

我尝试过原始字符串和转义斜杠,但都不起作用。我还尝试了 GetExpandedString() 方法,其行为相同。

它似乎因 sSubKeyName 值较长而失败,但这只是一种直觉。

编辑

Y__ 发布的代码的稍微简洁的版本

key = _winreg.OpenKey(
    _winreg.HKEY_LOCAL_MACHINE,
    "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{90140000-001F-040C-1000-0000000FF1CE}",
    0, _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY)

name = _winreg.QueryValueEx(key, "DisplayName")
print name[0]

最佳答案

我查看了您的代码,发现失败时,返回代码为 2 ,这意味着 ERROR_FILE_NOT_FOUND (引用:http://msdn.microsoft.com/en-us/library/ms681382%28v=3Dvs.%2085%29.aspx )

事实上,由于某种原因,我使用 regedit 看到的内容与使用此代码片段看到的内容不一致:

err_code, results = c.EnumKey (
    hDefKey=_winreg.HKEY_LOCAL_MACHINE,
    sSubKeyName="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
)
print err_code
for r in results:
    print result

我正在寻找对此行为的正确解释。

希望对你有帮助

最佳

编辑

我想我已经通过这篇文章找到了罪魁祸首 ( http://mail.python.org/pipermail/python-win32/2009-February/008865.html )。

因此,如果您使用 Python API 打开 key ,您可以根据需要获取数据。 这是一个小(丑陋)代码,应该可以解决这个问题:

key = _winreg.OpenKey(
    _winreg.HKEY_LOCAL_MACHINE, 
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E5D76AD-A3FB-48D5-8400-8903B10317D3}" ,
     0,
    _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY

i = 0
while True:
    try:
        name, val, key_type = _winreg.EnumValue(key, i)
        if name == "DisplayName":
            print "%s => %s" % (name, val)
        except:
            # No more indices
            break
        i += 1

其他引用:http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx

编辑2

根据您的评论,这里是一个代码片段,应该可以完成您想要的操作:

import _winreg

def getKeys(hKey, sSubKey):
    with _winreg.OpenKey(hKey, sSubKey, 0, _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY)     as key:
        idx = 0
        while True:
            try:
                yield _winreg.EnumKey(key, idx)
            except:
                # No more indices
                break
            idx += 1

hKey = _winreg.HKEY_LOCAL_MACHINE
sSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
for keyName in getKeys(hKey, sSubKey):
    with _winreg.OpenKey(hKey, "\\".join([sSubKey, keyName]) , 0, _winreg.KEY_READ |     _winreg.KEY_WOW64_64KEY) as key:
        i = 0
        while True:
            try:
                name, val, key_type = _winreg.EnumValue(key, i)
                if name == "DisplayName":
                    print "%s\\%s => %s" % (keyName, name, val)
                    break
            except:
                break

            i += 1

关于Python、WMI、注册表和奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14705293/

相关文章:

python - 安装 Chrome Native Client SDK

excel - 使用注册表安装 Excel AddIn

c++ - Win32 应用程序设置

delphi - 如何检查注册表项是否存在

python - 为什么 SIP 和 PyQt4 不能相处

python - txt 文件使用 .write() python 显示为空白

windows - 如何让 text-icu 在 Windows 上运行?

windows - 如何使用 PHP 在 Windows 上运行这些 Unix 类型的命令

python - 在Python中使用子进程时出现回溯错误

python - SQLite INNER JOIN in python : sqlite3. OperationalError: no such column: