2013-02-05 26 views
2

我需要創建一個python腳本來瀏覽HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall的內容並返回每個鍵的DisplayName。Python,WMI,註冊表和奇怪的結果

我用這個作爲出發地(在另一個計算器後發現)

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 

但是,如果我改變sSubKeyName和的sValueName(以有效值),這似乎是非常片狀,往往不是返回無。

例如:

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 

這導致無被打印。

然而,

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 

返回無

我試過原始字符串和逃離sl骨灰,都沒有工作。我也嘗試了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] 

回答

4

我在你的代碼一看,發現當它失敗,返回代碼爲2這意味着ERROR_FILE_NOT_FOUND( ref: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 = _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

EDIT 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 
+0

哇,謝謝。是否可以遍歷Uninstall鍵來查找所有子鍵的DisplayName?我查看了文檔(http://docs.python.org/2/library/_winreg.html),並找不到其他方法使用除了CreateKeyEx之外的標誌的方法。使用EnumKey將代碼提供給代碼看起來不起作用(文件未找到),我懷疑是因爲它從32位視圖中獲取值。 – mdj

+0

請注意,這段代碼只是您可以做的一個例子。 特別是,我沒有找到比使用'try'''''更好的方法來遍歷鍵和值... –

+0

真棒,我嘗試了幾種不同的方法,但無法使它工作。我將不得不花一些時間瞭解你的作品,謝謝! – mdj