[英]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.但是,如果我更改sSubKeyName
和sValueName
(为有效值),它似乎非常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.