简体   繁体   English

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

[英]Python, WMI, the registry, and strange results

I need to create a python script to go through the contents of HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall and return the DisplayName of each key.我需要创建一个 python 脚本来遍历HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall并返回每个键的DisplayName

I'm using this as a starting ground (found on another stack-overflow post)我将此用作起点(在另一个堆栈溢出帖子中找到)

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

That works.这样可行。 It returns:它返回:

\SystemRoot\system32\drivers\mrxdav.sys

However, if I change the sSubKeyName and sValueName (to valid values), it appears to be extremely flaky, returning None more often than not.但是,如果我更改sSubKeyNamesValueName (为有效值),它似乎非常sValueName ,经常返回None

For example:例如:

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

This results in None being printed.这导致None被打印。

However,然而,

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

Returns the correct value,返回正确的值,

C:\Windows\SysWOW64\

If we then try:如果我们然后尝试:

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

Returns None返回None

I've tried raw strings and escaping the slashes, neither have worked.我试过原始字符串和转义斜杠,都没有奏效。 I've also tried the GetExpandedString() method and it behaves identically.我也尝试过GetExpandedString()方法,它的行为相同。

It appears to fail with longer sSubKeyName values, but this is just a gut feeling.它似乎因sSubKeyName值较长而失败,但这只是一种直觉。

EDIT编辑

Slightly cleaner version of the code posted by Y__ 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]

I had a look at your code and noticed that when it fails, the return code is 2 which means ERROR_FILE_NOT_FOUND (ref : http://msdn.microsoft.com/en-us/library/ms681382%28v=3Dvs.%2085%29.aspx )我查看了您的代码并注意到当它失败时,返回代码为2 ,这意味着ERROR_FILE_NOT_FOUND (参考: http : //msdn.microsoft.com/en-us/library/ms681382%28v=3Dvs.%2085% 29.aspx )

And indeed, for some reason, what I see using regedit and what I see with this code snippet are inconsistent :事实上,出于某种原因,我使用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

I'm looking to find a proper explanation for this behavior.我正在寻找对这种行为的正确解释。

Hope it helps,希望能帮助到你,

Best最好

EDIT编辑

I think that I've found the culprit thanks to this post ( http://mail.python.org/pipermail/python-win32/2009-February/008865.html ).由于这篇文章( http://mail.python.org/pipermail/python-win32/2009-February/008865.html ),我认为我找到了罪魁祸首。

So if you use the Python API to open the key you may fetch your data as needed.因此,如果您使用 Python API 打开密钥,您可以根据需要获取数据。 Here is a small (ugly) code that should do the trick :这是一个应该可以解决问题的小(丑陋)代码:

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

Additional reference : http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx其他参考: http : //msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx

EDIT 2编辑 2

Following your comment, here is a code snippet that should do what you want :在您的评论之后,这里是一个代码片段,应该可以做您想做的事情:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM