Python winreg - How to write a linefeed to a REG_SZ value - python
I need some assistance in writing a line feed to a registry value. The Value is of type REG_SZ.
I'm able to do this manually, by adding a "0A" to each break position when modifying the hex value in the Registry, but I'm not sure how to do this programmatically.
This is my current code to write the String to Registry, which WORKS, but does not allow for the line feeds:
(identifying information redacted, and text shortened. The "#" is the position for a line feed)
import os
import _winreg
from _winreg import *
Key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Field = [_winreg.REG_SZ, _winreg.REG_BINARY]
Sub_Key = ["legalnoticetext",
"legalnoticecaption"]
value = ["Terms of Use",
"By logging in to this PC, users agree to the Terms of Use"
"\nThe User agrees to the following:#- The User may not alter, in any way, "
"with Settings on this PC without the approval from any Authorised Persons."]
parmLen = len(Sub_Key)
z = 0 # Loop Counter for list iteration
try:
Key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if not os.path.exists(Key):
key = _winreg.CreateKey(HKEY_LOCAL_MACHINE, Key)
Registrykey = OpenKey(HKEY_LOCAL_MACHINE, Key, 0, KEY_WRITE)
while z < parmLen:
_winreg.SetValueEx(Registrykey, Sub_Key[z], 0, Field[z], value[z])
print ("Setting <" + Sub_Key[z] + "> with value: " + value[z])
z += 1
CloseKey(Registrykey)
print ("SUCCESSFUL! Procedure: Show Logon Terms of Use")
except WindowsError:
print ("Error")
I've tested the following code to see if I can write directly in Hex, as I have the modified hex value, but it results in the value being interpreted as a string, and then formatting it incorrectly (again) to Hex.
import os
import _winreg
from _winreg import *
Key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Field = [_winreg.REG_SZ, _winreg.REG_BINARY]
Sub_Key = ["legalnoticetext",
"legalnoticecaption"]
value = ["Terms of Use",
"42,00,79,00,20,00,6C,00,6F,00,67,00,67,00,69,00,6E,00,67,00,20,00,69,00,"
"6E,00,20,00,74,00,6F,00,20,00,74,00,68,00,69,00,73,00,20,00,50,00,43,00,"
"2C,00,20,00,75,00,73,00,65,00,72,00,73,00,20,00,61,00,67,00,72,00,65,00,"
"65,00,20,00,74,00,6F,00,20,00,74,00,68,00,65,00,20,00,54,00,65,00,72,00,"
"6D,00,73,00,20,00,6F,00,66,00,20,00,55,00,73,00,65,00,0A,00,54,00,68,00,"
"65,00,20,00,55,00,73,00,65,00,72,00,20,00,61,00,67,00,72,00,65,00,65,00,"
"73,00,20,00,74,00,6F,00,20,00,74,00,68,00,65,00,20,00,66,00,6F,00,6C,00,"
"6C,00,6F,00,77,00,69,00,6E,00,67,00,3A,00,0A,00,2D,00,20,00,54,00,68,00,"
"65,00,20,00,55,00,73,00,65,00,72,00,20,00,6D,00,61,00,79,00,20,00,6E,00,"
"6F,00,74,00,20,00,61,00,6C,00,74,00,65,00,72,00,2C,00,20,00,69,00,6E,00,"
"20,00,61,00,6E,00,79,00,20,00,77,00,61,00,79,00,2C,00,20,00,77,00,69,00,"
"74,00,68,00,20,00,53,00,65,00,74,00,74,00,69,00,6E,00,67,00,73,00,20,00,"
"6F,00,6E,00,20,00,74,00,68,00,69,00,73,00,20,00,50,00,43,00,20,00,77,00,"
"69,00,74,00,68,00,6F,00,75,00,74,00,20,00,74,00,68,00,65,00,20,00,61,00,"
"70,00,70,00,72,00,6F,00,76,00,61,00,6C,00,20,00,66,00,72,00,6F,00,6D,00,"
"20,00,61,00,6E,00,79,00,20,00,41,00,75,00,74,00,68,00,6F,00,72,00,69,00,"
"73,00,65,00,64,00,20,00,50,00,65,00,72,00,73,00,6F,00,6E,00,73,00,2E,00,"
"00,00"]
parmLen = len(Sub_Key)
z = 0 # Loop Counter for list iteration
try:
Key = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
if not os.path.exists(Key):
key = _winreg.CreateKey(HKEY_LOCAL_MACHINE, Key)
Registrykey = OpenKey(HKEY_LOCAL_MACHINE, Key, 0, KEY_WRITE)
while z < parmLen:
_winreg.SetValueEx(Registrykey, Sub_Key[z], 0, Field[z], value[z])
print ("Setting <" + Sub_Key[z] + "> with value: " + value[z])
z += 1
CloseKey(Registrykey)
print ("SUCCESSFUL! Procedure: Show Logon Terms of Use")
except WindowsError:
print ("Error")
RTFM'ing doesn't prove to be very helpful with this specific issue, so any guidance would be appreciated!
You have a couple of issues going on. os.path.exists checks for file path existence. Feeding it the key string won't check the registry.
It looks like you are using Python 2.7, please consider upgrading to 3. The issue you are running into is that writing a REG_BINARY expects binary data; in Python 3, this means you just need to encode your string. Here is the code in Python 3.
import winreg
Key_str = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Field = [winreg.REG_SZ, winreg.REG_BINARY]
Sub_Key = ["legalnoticetext", "legalnoticecaption"]
value = ["Terms of Use",
"By logging in to this PC, users agree to the Terms of Use"
"\nThe User agrees to the following:#- The User may not alter, in any way, "
"with Settings on this PC without the approval from any Authorised Persons."]
try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, Key_str)
except FileNotFoundError:
key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, Key_str)
for sk, f, v in zip(Sub_Key, Field, value):
if f == winreg.REG_BINARY:
winreg.SetValueEx(key, sk, 0, f, v.encode('latin-1'))
else:
winreg.SetValueEx(key, sk, 0, f, v)
key.Close()
In Python 2, your standard strings are byte strings, so there is no need to encode the string to a bytes encoding. Here is the Python 2 code:
import _winreg
Key_str = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Field = [_winreg.REG_SZ, _winreg.REG_BINARY]
Sub_Key = ["legalnoticetext", "legalnoticecaption"]
value = ["Terms of Use",
"By logging in to this PC, users agree to the Terms of Use"
"\nThe User agrees to the following:#- The User may not alter, in any way, "
"with Settings on this PC without the approval from any Authorised Persons."]
try:
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, Key_str)
except WindowsError:
key = _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, Key_str)
for sk, f, v in zip(Sub_Key, Field, value):
_winreg.SetValueEx(key, sk, 0, f, v)
key.Close()
Related
Delete registry folder and sub folder using python [duplicate]
I'm trying to delete certain registry keys, via python script. i have no problems reading and deleting keys from the "HKEY_CURRENT_USER", but trying to do the same from the "HKEY_LOCAL_MACHINE", gives me the dreaded WindowsError: [Error 5] Access is denied. i'm running the script via the IDLE IDE, with admin privileges. here's the code: from _winreg import * ConnectRegistry(None,HKEY_LOCAL_MACHINE) OpenKey(HKEY_LOCAL_MACHINE,r'software\wow6432node\App',0,KEY_ALL_ACCESS) DeleteKey(OpenKey(HKEY_LOCAL_MACHINE,r'software\wow6432node'),'App')
You need to remove all subkeys before you can delete the key. def deleteSubkey(key0, key1, key2=""): import _winreg if key2=="": currentkey = key1 else: currentkey = key1+ "\\" +key2 open_key = _winreg.OpenKey(key0, currentkey ,0,_winreg.KEY_ALL_ACCESS) infokey = _winreg.QueryInfoKey(open_key) for x in range(0, infokey[0]): #NOTE:: This code is to delete the key and all subkeys. # If you just want to walk through them, then # you should pass x to EnumKey. subkey = _winreg.EnumKey(open_key, x) # Deleting the subkey will change the SubKey count used by EnumKey. # We must always pass 0 to EnumKey so we # always get back the new first SubKey. subkey = _winreg.EnumKey(open_key, 0) try: _winreg.DeleteKey(open_key, subkey) print "Removed %s\\%s " % ( currentkey, subkey) except: deleteSubkey( key0, currentkey, subkey ) # no extra delete here since each call #to deleteSubkey will try to delete itself when its empty. _winreg.DeleteKey(open_key,"") open_key.Close() print "Removed %s" % (currentkey) return Here is an how you run it: deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node", "App") deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node\\App")
Just my two cents on the topic, but I recurse to the lowest subkey and delete on unravel: def delete_sub_key(root, sub): try: open_key = winreg.OpenKey(root, sub, 0, winreg.KEY_ALL_ACCESS) num, _, _ = winreg.QueryInfoKey(open_key) for i in range(num): child = winreg.EnumKey(open_key, 0) delete_sub_key(open_key, child) try: winreg.DeleteKey(open_key, '') except Exception: # log deletion failure finally: winreg.CloseKey(open_key) except Exception: # log opening/closure failure The difference between the other posts is that I do not try to delete if num is >0 because it will fail implicitly (as stated in the docs). So I don't waste time to try if there are subkeys.
[EDIT] I have created a pip package that handles registry keys. Install with: pip install windows_tools.registry Usage: from windows_tools.registry import delete_sub_key, KEY_WOW64_32KEY, KEY_WOW64_64KEY keys = ['SOFTWARE\MyInstalledApp', 'SOFTWARE\SomeKey\SomeOtherKey'] for key in keys: delete_sub_key(key, arch=KEY_WOW64_32KEY | KEY_WOW64_64KEY) [/EDIT] Unburying this old question, here's an updated version of ChrisHiebert's recursive function that: Handles Python 3 (tested with Python 3.7.1) Handles multiple registry architectures (eg Wow64 for Python 32 on Windows 64) Is PEP-8 compliant The following example shows function usage to delete two keys in all registry architectures (standard and redirected WOW6432Node) by using architecture key masks. Hopefully this will help someone: import winreg def delete_sub_key(key0, current_key, arch_key=0): open_key = winreg.OpenKey(key0, current_key, 0, winreg.KEY_ALL_ACCESS | arch_key) info_key = winreg.QueryInfoKey(open_key) for x in range(0, info_key[0]): # NOTE:: This code is to delete the key and all sub_keys. # If you just want to walk through them, then # you should pass x to EnumKey. sub_key = winreg.EnumKey(open_key, x) # Deleting the sub_key will change the sub_key count used by EnumKey. # We must always pass 0 to EnumKey so we # always get back the new first sub_key. sub_key = winreg.EnumKey(open_key, 0) try: winreg.DeleteKey(open_key, sub_key) print("Removed %s\\%s " % (current_key, sub_key)) except OSError: delete_sub_key(key0, "\\".join([current_key,sub_key]), arch_key) # No extra delete here since each call # to delete_sub_key will try to delete itself when its empty. winreg.DeleteKey(open_key, "") open_key.Close() print("Removed %s" % current_key) return # Allows to specify if operating in redirected 32 bit mode or 64 bit, set arch_keys to 0 to disable arch_keys = [winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY] # Base key root = winreg.HKEY_LOCAL_MACHINE # List of keys to delete keys = ['SOFTWARE\MyInstalledApp', 'SOFTWARE\SomeKey\SomeOtherKey'] for key in keys: for arch_key in arch_keys: try: delete_sub_key(root, key, arch_key) except OSError as e: print(e)
Figured it out! turns out the registry key wasn't empty and contained multiple subkeys. i had to enumerate and delete the subkeys first, and only then i was able to delete the main key from HKLM. (also added "try...except", so it wouldn't break the whole code, it case there were problems).
This is my solution. I like to use with statements in order to not have to close the key manually. First I check for sub keys and delete them before I delete the key itself. EnumKey raises an OSError if no sub key exists. I use this to break out of the loop. from winreg import * def delete_key(key: Union[HKEYType, int], sub_key_name: str): with OpenKey(key, sub_key_name) as sub_key: while True: try: sub_sub_key_name = EnumKey(sub_key, 0) delete_key(sub_key, sub_sub_key_name) except OSError: break DeleteKey(key, sub_key_name)
Can't save the data in shelve module Python
I want to create a python file that when user inputs a value, it will save to a dictionary and update the binary file created by shelve module. The problem is that when I run the python file again, the dictionary is not updated. There is no error code or anything and I don't know what to do. import shelve menubook = shelve.open('menu_data', writeback=True) menubookA = {'main':'toast', 'sub':'egg', 'drink':'milk'} print(menubookA) print(menubookA['drink']) key = input("Enter key: ") value = input("Enter value: ") menubookA[key] = value print(menubookA) # When I check the dictionary here, it has been updated but when I run the program again, the value and key added are gone. menubook.close() I would appreciate if anyone could help me.
You obviously forgot to write the data back to the file: import shelve menubook = shelve.open("menu_data", writeback=True) # Read data from the file for key, value in menubook.items(): print("Key: %s = %s" % (key, value)) menubookA = {"main": "toast", "sub": "egg", "drink": "milk"} print(menubookA) print(menubookA["drink"]) key = input("Enter key: ") value = input("Enter value: ") menubookA[key] = value print(menubookA) # When I check the dictionary here, it has been updated but when I run the program again, the value and key added are gone. # Write data back to the file menubook.update(menubookA) menubook.close()
Is there a way to get the full path of the shell:appsfolder on Windows 10?
I'd like to be able to list the files in the shell:appsfolder in a python script but need the full path to do this using os.list. Is there a way to get the full path (or does anyone know it)? Alternatively, is there a different way I can list these files? Can I "cd" to it? The idea behind the script is to automate the shortcut creation of all the Windows Store apps (identified by the fact they have a "long name" property I think) and extract those shortcuts to a folder where the program Launchy can detect them. I don't like having to manually go through the process of creating the shortcut (and renaming it to remove the " - shortcut) every time I download or remove an app so I thought I'd automate it.
Here's a function that hopefully does what you want in terms of creating shortcuts for the Windows Store apps that are listed in the "Applications" virtual folder (i.e. FOLDERID_AppsFolder). To classify Windows Store apps, it looks for an exclamation point in the Application User Model ID since the AUMID should be of the form "PackageFamily!ApplicationID" (see Automate Launching UWP Apps). For reliability it cross-checks each package family with the user's registered package families. import os import ctypes import pywintypes import pythoncom import winerror try: import winreg except ImportError: # Python 2 import _winreg as winreg bytes = lambda x: str(buffer(x)) from ctypes import wintypes from win32com.shell import shell, shellcon from win32com.propsys import propsys, pscon # KNOWNFOLDERID # https://msdn.microsoft.com/en-us/library/dd378457 # win32com defines most of these, except the ones added in Windows 8. FOLDERID_AppsFolder = pywintypes.IID('{1e87508d-89c2-42f0-8a7e-645a0f50ca58}') # win32com is missing SHGetKnownFolderIDList, so use ctypes. _ole32 = ctypes.OleDLL('ole32') _shell32 = ctypes.OleDLL('shell32') _REFKNOWNFOLDERID = ctypes.c_char_p _PPITEMIDLIST = ctypes.POINTER(ctypes.c_void_p) _ole32.CoTaskMemFree.restype = None _ole32.CoTaskMemFree.argtypes = (wintypes.LPVOID,) _shell32.SHGetKnownFolderIDList.argtypes = ( _REFKNOWNFOLDERID, # rfid wintypes.DWORD, # dwFlags wintypes.HANDLE, # hToken _PPITEMIDLIST) # ppidl def get_known_folder_id_list(folder_id, htoken=None): if isinstance(folder_id, pywintypes.IIDType): folder_id = bytes(folder_id) pidl = ctypes.c_void_p() try: _shell32.SHGetKnownFolderIDList(folder_id, 0, htoken, ctypes.byref(pidl)) return shell.AddressAsPIDL(pidl.value) except WindowsError as e: if e.winerror & 0x80070000 == 0x80070000: # It's a WinAPI error, so re-raise it, letting Python # raise a specific exception such as FileNotFoundError. raise ctypes.WinError(e.winerror & 0x0000FFFF) raise finally: if pidl: _ole32.CoTaskMemFree(pidl) def enum_known_folder(folder_id, htoken=None): id_list = get_known_folder_id_list(folder_id, htoken) folder_shell_item = shell.SHCreateShellItem(None, None, id_list) items_enum = folder_shell_item.BindToHandler(None, shell.BHID_EnumItems, shell.IID_IEnumShellItems) for item in items_enum: yield item def list_known_folder(folder_id, htoken=None): result = [] for item in enum_known_folder(folder_id, htoken): result.append(item.GetDisplayName(shellcon.SIGDN_NORMALDISPLAY)) result.sort(key=lambda x: x.upper()) return result def create_shortcut(shell_item, shortcut_path): id_list = shell.SHGetIDListFromObject(shell_item) shortcut = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink) shortcut.SetIDList(id_list) persist = shortcut.QueryInterface(pythoncom.IID_IPersistFile) persist.Save(shortcut_path, 0) def get_package_families(): families = set() subkey = (r'Software\Classes\Local Settings\Software\Microsoft' r'\Windows\CurrentVersion\AppModel\Repository\Families') with winreg.OpenKey(winreg.HKEY_CURRENT_USER, subkey) as hkey: index = 0 while True: try: families.add(winreg.EnumKey(hkey, index)) except OSError as e: if e.winerror != winerror.ERROR_NO_MORE_ITEMS: raise break index += 1 return families def update_app_shortcuts(target_dir): package_families = get_package_families() for item in enum_known_folder(FOLDERID_AppsFolder): try: property_store = item.BindToHandler(None, shell.BHID_PropertyStore, propsys.IID_IPropertyStore) app_user_model_id = property_store.GetValue( pscon.PKEY_AppUserModel_ID).ToString() except pywintypes.error: continue # AUID template: Packagefamily!ApplicationID if '!' not in app_user_model_id: continue package_family, app_id = app_user_model_id.rsplit('!', 1) if package_family not in package_families: continue name = item.GetDisplayName(shellcon.SIGDN_NORMALDISPLAY) shortcut_path = os.path.join(target_dir, '%s.lnk' % name) create_shortcut(item, shortcut_path) print('{}: {}'.format(name, app_user_model_id)) example if __name__ == '__main__': desktop = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, 0, 0) target_dir = os.path.join(desktop, 'Windows Store Apps') if not os.path.exists(target_dir): os.mkdir(target_dir) update_app_shortcuts(target_dir)
How to programmatically calculate Chrome extension ID?
I'm building an automated process to produce extensions. Is there a code example of calculating the extension-ID directly and entirely bypassing interaction with the browser? (I'm answering my own question, below.)
I was only able to find a related article with a Ruby fragment, and it's only available in the IA: http://web.archive.org/web/20120606044635/http://supercollider.dk/2010/01/calculating-chrome-extension-id-from-your-private-key-233 Important to know: This depends on a DER-encoded public key (raw binary), not a PEM-encoded key (nice ASCII generated by base64-encoding the DER key). The extension-IDs are base-16, but are encoded using [a-p] (called "mpdecimal"), rather than [0-9a-f]. Using a PEM-encoded public key, follow the following steps: If your PEM-formatted public-key still has the header and footer and is split into multiple lines, reformat it by hand so that you have a single string of characters that excludes the header and footer, and runs together such that every line of the key wraps to the next. Base64-decode the public key to render a DER-formatted public-key. Generate a SHA256 hex-digest of the DER-formatted key. Take the first 32-bytes of the hash. You will not need the rest. For each character, convert it to base-10, and add the ASCII code for 'a'. The following is a Python routine to do this: import hashlib from base64 import b64decode def build_id(pub_key_pem): pub_key_der = b64decode(pub_key_pem) sha = hashlib.sha256(pub_key_der).hexdigest() prefix = sha[:32] reencoded = "" ord_a = ord('a') for old_char in prefix: code = int(old_char, 16) new_char = chr(ord_a + code) reencoded += new_char return reencoded def main(): pub_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjvF5pjuK8gRaw/2LoRYi37QqRd48B/FeO9yFtT6ueY84z/u0NrJ/xbPFc9OCGBi8RKIblVvcbY0ySGqdmp0QsUr/oXN0b06GL4iB8rMhlO082HhMzrClV8OKRJ+eJNhNBl8viwmtJs3MN0x9ljA4HQLaAPBA9a14IUKLjP0pWuwIDAQAB' id_ = build_id(pub_key) print(id_) if __name__ == '__main__': main() You're more than welcome to test this against an existing extension and its ID. To retrieve its PEM-formatted public-key: Go into the list of your existing extensions in Chrome. Grab the extension-ID of one. Find the directory where the extension is hosted. On my Windows 7 box, it is: C:\Users<username>\AppData\Local\Google\Chrome\User Data\Default\Extensions<extension ID> Grab the public-key from the manifest.json file under "key". Since the key is already ready to be base64-decoded, you can skip step (1) of the process. The public-key in the example is from the "Chrome Reader" extension. Its extension ID is "lojpenhmoajbiciapkjkiekmobleogjc". See also: Google Chrome - Alphanumeric hashes to identify extensions http://blog.roomanna.com/12-14-2010/getting-an-extensions-id
Starting with Chrome 64, Chrome changed the package format for extensions to the CRX₃ file format, which supports multiple signatures and explicitly declares its CRX ID. Extracting the CRX ID from a CRX₃ file requires parsing a protocol buffer. Here is a small python script for extracting the ID from a CRX₃ file. This solution should only be used with trusted CRX₃ files or in contexts where security is not a concern: unlike CRX₂, the package format does not restrict what CRX ID a CRX₃ file declares. (In practice, consumers of the file (i.e. Chrome) will place restrictions upon it, such as requiring the file to be signed with at least one key that hashes to the declared CRX ID). import binascii import string import struct import sys def decode(proto, data): index = 0 length = len(data) msg = dict() while index < length: item = 128 key = 0 left = 0 while item & 128: item = data[index] index += 1 value = (item & 127) << left key += value left += 7 field = key >> 3 wire = key & 7 if wire == 0: item = 128 num = 0 left = 0 while item & 128: item = data[index] index += 1 value = (item & 127) << left num += value left += 7 continue elif wire == 1: index += 8 continue elif wire == 2: item = 128 _length = 0 left = 0 while item & 128: item = data[index] index += 1 value = (item & 127) << left _length += value left += 7 last = index index += _length item = data[last:index] if field not in proto: continue msg[proto[field]] = item continue elif wire == 5: index += 4 continue raise ValueError( 'invalid wire type: {wire}'.format(wire=wire) ) return msg def get_extension_id(crx_file): with open(crx_file, 'rb') as f: f.read(8); # 'Cr24\3\0\0\0' data = f.read(struct.unpack('<I', f.read(4))[0]) crx3 = decode( {10000: "signed_header_data"}, [ord(d) for d in data]) signed_header = decode( {1: "crx_id"}, crx3['signed_header_data']) return string.translate( binascii.hexlify(bytearray(signed_header['crx_id'])), string.maketrans('0123456789abcdef', string.ascii_lowercase[:16])) def main(): if len(sys.argv) != 2: print 'usage: %s crx_file' % sys.argv[0] else: print get_extension_id(sys.argv[1]) if __name__ == "__main__": main() (Thanks to https://github.com/thelinuxkid/python-protolite for the protobuf parser skeleton.)
A nice and simple way to get the public key from the .crx file using python, since chrome only generates the private .pem key for you. The public key is actually stored in the .crx file. This is based on the format of the .crx file found here http://developer.chrome.com/extensions/crx.html import struct import hashlib import string def get_pub_key_from_crx(crx_file): with open(crx_file, 'rb') as f: data = f.read() header = struct.unpack('<4sIII', data[:16]) pubkey = struct.unpack('<%ds' % header[2], data[16:16+header[2]])[0] return pubkey def get_extension_id(crx_file): pubkey = get_pub_key_from_crx(crx_file) digest = hashlib.sha256(pubkey).hexdigest() trans = string.maketrans('0123456789abcdef', string.ascii_lowercase[:16]) return string.translate(digest[:32], trans) if __name__ == '__main__': import sys if len(sys.argv) != 2: print 'usage: %s crx_file' % sys.argv[0] print get_extension_id(sys.argv[1]) Although this isn't possible to do "bypassing interaction with the browser", because you still need to generate the .crx file with a command like chrome.exe --pack-extension=my_extension --pack-extension-key=my_extension.pem
Python winreg looping through sub-keys
I'm able to successfully retrieve the 5 sub-keys from my windows 7 machine registry hive "HKEY_LOCAL_MACHINE" with the code below. from _winreg import * try: i = 0 while True: subkey = EnumKey(HKEY_LOCAL_MACHINE, i) print subkey i += 1 except WindowsError: pass My question is, how do I then enumerate the keys under those? I want to end up listing all the keys in the SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged folder but I can't figure out how to step my way down there. In response to the first comment, I ran this code on my machine and while it didn't error out, it didn't produce results. from _winreg import * aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged") for i in range(1024): try: keyname = EnumKey(aKey, i) asubkey = OpenKey(aKey, keyname) val = QueryValueEx(asubkey, "Description") print val except WindowsError: break A regedit or reg query shows 6 values in that folder but I can't get a python script to show me those six.
Just want to add a perhaps more pythonic solution. from _winreg import * from contextlib import suppress import itertools def subkeys(path, hkey=HKEY_LOCAL_MACHINE, flags=0): with suppress(WindowsError), OpenKey(hkey, path, 0, KEY_READ|flags) as k: for i in itertools.count(): yield EnumKey(k, i) You can now access the keys as expected for key in subkeys(r'path\to\your\key'): print key For python versions < 3.4 that lack suppress(), I recommend adding it to your project: from contextlib import contextmanager #contextmanager def suppress(*exceptions): try: yield except exceptions: pass Note: If you have trouble reading some values you might be reading from the wrong registry view. Pass KEY_WOW64_64KEY or KEY_WOW64_32KEY to the flags parameter). Using OpenKey() as context manager was introduced in python 2.6.
Does something like this work? import _winreg def subkeys(key): i = 0 while True: try: subkey = _winreg.EnumKey(key, i) yield subkey i+=1 except WindowsError: break def traverse_registry_tree(key=_winreg.HKEY_LOCAL_MACHINE, tabs=0): for k in subkeys(key): print '\t'*tabs + str(k) traverse_registry_tree(k, tabs+1)
I don't have the same registry keys to search but the following code will list all the subkeys in HKEY_LOCAL_MACHINE\Software. I think if you change the value of the keyVal string to your directory it will work. The try ... except bloc is this way because EnumKey will fail. I didn't do it as a for loop because I dont know how to get the correct length of aKey. keyVal = r"Software" aKey = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS) try: i = 0 while True: asubkey = EnumKey(aKey, i) print(asubkey) i += 1 except WindowsError: pass
This works, and prints out the list of all subkeys (fixed version of #Broseph's answer) import _winreg def subkeys(key): i = 0 while True: try: subkey = _winreg.EnumKey(key, i) yield subkey i+=1 except WindowsError as e: break def traverse_registry_tree(hkey, keypath, tabs=0): key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ) for subkeyname in subkeys(key): print '\t'*tabs + subkeyname subkeypath = "%s\\%s" % (keypath, subkeyname) traverse_registry_tree(hkey, subkeypath, tabs+1) keypath = r"SOFTWARE\\Microsoft\\Windows" traverse_registry_tree(_winreg.HKEY_LOCAL_MACHINE, keypath)
For iterating through keys of Windows registry, you would need EnumKey() from _winreg module. Given below is the definition for EnumKey() :- def EnumKey(key, index): Enumerates subkeys of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. index is an integer that identifies the index of the key to retrieve. Note that this method, takes index as an argument, and will provide you the key only for the given index. Therefore, in order to get all the keys, you need to increment the index by one and continue until you encounter WindowsError. Refer to this post for a detailed understanding on the same. The Github link for the code can be found in the post.
this is just an improvement on #sparrowt's answer. His answer failed when I tried it, but think it was on the right track. This will give tree below keypath. Sorry for changing some variable and method names in rewrite, but just trying to post this quick. In my code, I put hkey as global variable bc I expect to only be working with one hkey at a time. import winreg import itertools hkey = winreg.HKEY_LOCAL_MACHINE def list_subkeys(path, hkey_set=None): global hkey if not hkey_set: hkey_set = hkey try: registry_key = winreg.OpenKey(hkey_set, path, 0, winreg.KEY_READ) for i in itertools.count(): yield winreg.EnumKey(registry_key, i) winreg.CloseKey(registry_key) except Exception as ex: if str(ex) != '[WinError 259] No more data is available': print(str(ex)) try: winreg.CloseKey(registry_key) except: pass return [] def traverse_registry_tree(keypath, levels=None, hkey_set=None): global hkey if not levels: levels = [] if not hkey_set: hkey_set = hkey subkeys = list(list_subkeys(keypath, hkey_set)) for subkeyname in subkeys: subkeypath = "%s\\%s" % (keypath, subkeyname) levels.append(subkeypath) levels.extend([r for r in traverse_registry_tree(subkeypath, levels, hkey_set) if r not in levels]) del subkeys return levels
I made this code. It prints the whole subtree of a key. But first, I would like to say that the following code does not use the original naming: [key] |-[key] | └-[value1: data] |-[value1: data] └-[value2: data] I use the following scheme [folder] |-[subfolder] | └-[key1: value] |-[key1: value] └-[key2: value] import winreg def padding(cnt): str = "" for i in range(cnt): str += '\t' return str def recursive_visit(folder, i): subfolders_count, subkeys_count, modified = winreg.QueryInfoKey(folder) for subfolder_index in range(subfolders_count): try: subfolder_name = winreg.EnumKey(folder, subfolder_index) print(padding(i)+subfolder_name+":") with winreg.OpenKeyEx(folder, subfolder_name) as subfolder: recursive_visit(subfolder, i+1) except (WindowsError, KeyError, ValueError): print("Error reading " + folder) for subkey_index in range(subkeys_count): print(padding(i)+str(winreg.EnumValue(folder, subkey_index))) globals()["cnt"] += 1 cnt = 0 #how many keys we visited ### ENTER INPUT HERE root = winreg.HKEY_LOCAL_MACHINE folder = r"SYSTEM\Setup\FirstBoot\Services" ### with winreg.OpenKey(root, folder) as reg: keys_count, values_count, modified = winreg.QueryInfoKey(reg) print("Subfolders: " + str(keys_count) + " Subkeys: " + str(values_count)) recursive_visit(reg, 1) print("visited " + str(cnt) + " leaf keys") This gives you the following output: Subkeys: 72 Subvalues: 1 AdobeARMservice: ('ServiceName', 'AdobeARMservice', 1) ('Path', '"C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe"', 1) ('Path.Org', '"C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe"', 1) ('Path.Win32', 'C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe', 1) ('StartName', 'LocalSystem', 1) ('DisplayName', 'Adobe Acrobat Update Service', 1) ('Type', 16, 4) ('StartType', 2, 4) ('ErrorControl', 0, 4) ('LoadOrderGroup', '', 1) ('TagId', 0, 4) AdobeUpdateService: ('ServiceName', 'AdobeUpdateService', 1) ...