Deleting subkeys under a key - python

I want to be able to delete all the subkeys under a key but I keep getting the error
[WinError 2] The system cannot find the file specified
Here is the code I used from another answer (python: how to delete registry key (and subkeys) from HKLM (getting error 5)1) :
import winreg
def delete_sub_key(key0, current_key, arch_key=0):
open_key = winreg.OpenKey(key0, current_key, 0, winreg.KEY_ALL_ACCESS)
info_key = winreg.QueryInfoKey(open_key)
for x in range(0, info_key[0]):
# to delete the key and all sub_keys
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
arch_keys = [winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY]
root = winreg.HKEY_LOCAL_MACHINE
# Key to delete
keys = 'Computer\\HKEY_LOCAL_MACHINE\\SOFTWARE\\BlueStacks'
for arch_key in arch_keys:
try:
delete_sub_key(root, keys, arch_key)
except OSError as e:
print(e)

Related

Python Windows Registry: Display List of Profiles

I am new to Windows Registries and I'm currently trying to get a list of profile names from my Windows registries using Python, but I am not sure what I'm doing wrong. My code is the following:
from winreg import *
def get_profiles():
regKey = OpenKey(HKEY_LOCAL_MACHINE,
r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList')
recent = QueryValueEx(regKey,'DisplayName')[0]
recent_list = []
for subkey in recent:
recent_list.append(QueryValueEx(regKey,subkey)[0])
return recent_list
When I try to run the above, I get the following:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-45-6261438d1fdc> in <module>()
----> 1 l = get_profiles()
<ipython-input-44-f572c6ac8843> in get_profiles()
4 regKey = OpenKey(HKEY_LOCAL_MACHINE,
5 r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList')
----> 6 recent = QueryValueEx(regKey,'DisplayName')[0]
7 recent_list = []
8 for subkey in recent:
FileNotFoundError: [WinError 2] The system cannot find the file specified
I have a hunch that the 'DisplayName' part is wrong, how should I correct it?
You can use EnumKey to get the sub keys of an open registry key.
winreg.EnumKey(key, index)
Enumerates subkeys of an open registry key,
returning a string.
key is an already open key, or one of the predefined HKEY_* constants.
index is an integer that identifies the index of the key to retrieve.
from contextlib import suppress
from winreg import \
(OpenKey,
HKEY_LOCAL_MACHINE,
QueryInfoKey,
QueryValueEx,
EnumKey)
PROFILE_REGISTRY = "SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\ProfileList"
def get_profile_attribute(*, attribute):
profile_to_sub_key_map = {}
with OpenKey(HKEY_LOCAL_MACHINE, PROFILE_REGISTRY) as key:
number_of_sub_keys, _, _ = QueryInfoKey(key) # The `QueryInfoKey` Returns information about a key, as a tuple.
# At the index 0 will be An integer giving the number of sub keys
# this key has.
for index in range(number_of_sub_keys):
sub_key_name = EnumKey(key, index)
# Open the sub keys one by one and fetch the attribute.
with OpenKey(HKEY_LOCAL_MACHINE,
f"{PROFILE_REGISTRY}\\{sub_key_name}") as sub_key:
with suppress(FileNotFoundError):
registry_value, _ = QueryValueEx(sub_key, attribute)
profile_to_sub_key_map.update({sub_key_name: registry_value})
return profile_to_sub_key_map
print(get_profile_attribute(attribute='ProfileImagePath'))
Also note that as per the documentation.
The HKEY object implements __enter__() and __exit__() and thus supports the context protocol for the with statement:
with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key:
... # work with key
will automatically close key when control leaves the with block.

skipping a json key if does not exist

I'm running the following:
for server in server_list:
for item in required_fields:
print item, eval(item)
There is a possibility that some keys may not exist, but worse it's represented on a parent key not the one I'm scanning for.
So I'm scanning the json for the following key:
server['server_management']['server_total_cost_of_ownership']['description']
Which doesn't exist but it's actually the parent that is null:
server['server_management']['server_total_cost_of_ownership']
How do I write my code to account for this? It's not giving a key error. Right now I get the following traceback:
Traceback (most recent call last):
File "C:/projects/blah/scripts/test.py", line 29, in <module>
print item, eval(item)
File "<string>", line 1, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'
Full code:
import csv
import json
import os
import requests
import sys
required_fields = ["server['server_name']","server['server_info']['asset_type']['display_name']",
"server['asset_status']['display_name']", "server['record_owner']['group_name']",
"server['server_management']['server_total_cost_of_ownership']['description']",
"server['server_management']['primary_business_owner']['name']",
"server['environment']['display_name']", "server['is_virtual']",
"server['managed_by']['display_name']", "server['server_info']['billable_ibm']",
"server['server_info']['billing_sub_type']['display_name']",
"server['server_info']['serial_number']", "server['location']['display_name']",
"server['inception_date']", "server['server_info']['decommission_date']" ]
# Query API for all servers
def get_servers_info():
servers_info = requests.get('url')
return servers_info.json()
def get_server_info(sid):
server_info = requests.get('url')
return server_info.json()
server_list = get_servers_info()
for server in server_list:
for item in required_fields:
print item, eval(item)
In fact you should avoid eval. After the json load since you know the key name, you can use a list to go deeper in the tree.
server['server_management']['primary_business_owner']['name']" => ["server_management', 'primary_business_owner', 'name']
Here a snippet for a json validation against a list of required fields.
data={
"d": {
"p":{
"r":[
"test"
]
}
},
"a": 3
}
def _get_attr(dict_, attrs):
try:
src = attrs[:]
root = attrs.pop(0)
node = dict_[root]
null = object()
for i, attr in enumerate(attrs[:]):
try:
node = node.get(attr, null)
except AttributeError:
node = null
if node is null:
# i+2 pop and last element
raise ValueError("%s not present (level %s)" % (attr, '->'.join(src[: i+2])))
return node
except KeyError:
raise ValueError("%s not present" % root)
# assume list of required field
reqs = [
["d", "p", "r"],
["d"],
["k"],
["d", "p", "r", "e"],
]
for req in reqs:
try:
_get_attr(data, req)
except ValueError as E:
print(E)
# prints
# k not present
# e not present (level d->p->r->e)
Ignoring the context of the code and not understanding the use of eval here, the way to do this is to use .get() and seed it with reasonable defaults.
For example:
server['server_management']['server_total_cost_of_ownership']['description']
Can be:
server.get('server_management', {}).get('server_total_cost_of_ownership', {}).get('description', '')
Then if any of the keys do not exist you will always get back an empty description ''.
Your problem here is totally unrelated to using eval[1]. The exception you get is the same as if the code would have been there directly. What you are running (via eval) is:
a = server['server_management']
b = a['server_total_cost_of_ownership']
c = b['description']
Yet, b is None, so resolving it to c will fail. Like a KeyError, you can also catch a TypeError:
for server in server_list:
for item in required_fields:
try:
print item, eval(item)
except TypeError:
print("Guess you're lucky you didn't include a fork bomb in your own code to eval.")
You may of course alternatively pass, print the offending item, open a browser to some page or do whatever error handling is appropriate given your input data.
[1] While not bickering around, I've made a new answer that works without eval. You can use precisely the same error handling:
for server in server_list:
for item in required_fields:
value = server
for key in parse_fields(field):
try:
value = value[key]
except TypeError:
print("Remember Kiddo: Eval is Evil!")
break
else: # for: else: triggers only if no break was issued
print item, value

Save KeyErrors and IndexErrors to a list/dict

I'm trying to extract data from an API, and I expect to receive KeyError and IndexError, so I use the try/except function to catch them. I first create a list of items that I'll loop through to extract information from the API responses. Then I create a dataframe that stores information about items that had no errors.
l= ["a","b","c","d"]
def extract_info_from_one_response(response, idx):
try:
response = response.json()
d = {
### some codes ##
}
## ERROR MANAGEMENT
except KeyError,e:
print idx, l[idx], str(e)
return {}
except IndexError,e:
print idx, l[idx], str(e)
return {}
dat = pd.DataFrame([extract_info_from_one_response(response, idx) for idx, response in enumerate(responses)], index=l)
When errors occur, Python prints out [1]the index of the problematic item, [2] the name of the item and [3]the details on the error that took place. How do I save/capture these three outputs, save them into objects or create a dataframe with these 3 pieces of information?
Are you asking how to trace the error?
If so,the traceback module would help like this:
In [1]: import traceback
In [2]: try:
...: a = []
...: a[2] = 1
...: except Exception:
...: y = traceback.format_exc()
...:
In [4]: print y
Traceback (most recent call last):
File "<ipython-input-2-ac34fe2721d3>", line 3, in <module>
a[2] = 1
IndexError: list assignment index out of range
I am not sure what you are asking, but if you want to save what is printed:
key_err = []
idx_err = []
def extract_info_from_one_response(response, idx):
try:
# your code here
except KeyError, e:
key_err.append((idx, l[idx], '{}'.format(e),))
return {}
except IndexError, e:
idx_err.append((idx, l[idx], '{}'.format(e),))
return {}
# your normal code here
# you need to return something here
dat = pd.DataFrame([extract_info_from_one_response(response, idx) for idx, response in enumerate(responses)], index=l)
print(key_err)
print(idx_err)

Get key name from Python KeyError exception

I would like to get the key name from the Python KeyError exception:
For example:
myDict = {'key1':'value1'}
try:
x1 = myDict['key1']
x2 = myDict['key2']
except KeyError as e:
# here i want to use the name of the key that was missing which is 'key2' in this example
print error_msg[missing_key]
i have already tried this
print e
print e.args
print e.message
my code is inside django view !
if i use ipython for example and try e.arg or e.message it works fine.
but then i try it while inside a django view i get this results:
"Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>"
("Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>",)
Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>
while i just want the 'key2'
You can use e.args:
[53]: try:
x2 = myDict['key2']
except KeyError as e:
print e.args[0]
....:
key2
From the docs:
The except clause may specify a variable after the exception name (or
tuple). The variable is bound to an exception instance with the
arguments stored in instance.args
myDict = {'key1':'value1'}
try:
x1 = myDict['key1']
x2 = myDict['key2']
except KeyError as e:
# here i want to use the name of the key that was missing which is 'key2' in this example
print "missing key in mydict:", e.message
For KeyErrors, the 2nd element (index 1) of sys.exc_info() holds the key:
import sys
try:
x1 = myDict['key1']
x2 = myDict['key2']
except KeyError:
print 'KeyError, offending key:', sys.exc_info()[1]
Output:
KeyError, offending key: 'key2'
Simply, the response of the KeyError is the key itself in case you want to make use of it you just need to call the error as it is.
myDict = {'key1':'value1'}
try:
x1 = myDict['key1']
x2 = myDict['key2']
except KeyError as missing_key:
# Used as missing_key for readability purposes only
print(f"Trying to access a <dict> with a missing key {missing_key}")
P.S. This was tested on Python version 3.8.12
As your dictionary is actually a QueryDict, and therefore returns a different error message, you will need to parse the exception message to return the first word in single quotes:
import re
#...
except KeyError as e:
m = re.search("'([^']*)'", e.message)
key = m.group(1)

Checking if a registry key exists python

I am encountering a small hiccup in the installer I am creating in python. I have a function which returns the value of a key based on it's location.
def CheckRegistryKey(registryConnection, location, softwareName, keyName):
'''
Check the windows registry and return the key value based on location and keyname
'''
try:
if registryConnection == "machine":
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
elif registryConnection == "user":
aReg = ConnectRegistry(None,HKEY_CURRENT_USER)
aKey = OpenKey(aReg, location)
except Exception, ex:
print ex
return False
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
pass
I get an error if the location does not exist. I want the function to return False so if the location does not exist so I can run the software installer, bit it always lands up in the exception
# check if the machine has .VC++ 2010 Redistributables and install it if needed
try:
hasRegistryKey = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))
if hasRegistryKey != False:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
if keyCheck == 1:
print 'vc++ 2010 redist installed'
else:
print 'installing VC++ 2010 Redistributables'
os.system(productsExecutables + 'vcredist_x86.exe /q /norestart')
print 'VC++ 2010 Redistributables installed'
except Exception, ex:
print ex
The exception I get when I run the code is
'NoneType' object has no attribute '___getitem___'
and the error I get from the def CheckRegistryKey function is
[Error 2] The system cannot find the file specified
What I need to do is check if the registry key or location exists, if not direct it to an executable. Any help is appreciated.
Thank you
The reason for the error:
'NoneType' object has no attribute '___getitem___'
Is in the line:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
The fragment edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed") is returning None.
This means you end up with:
keyCheck = (None)[0]
This is what is throwing your error. You are trying to get an item on a object that is None.
The reason that this you are getting None back from your CheckRegistryKey function is that if an error occurs you aren't returning anything. You need to return False when you catch a EnvironmentError:
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
return False
I would also modify your code so that you are only calling CheckRegistryKey once:
registryKey = edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed")
if registryKey is not False:
keyCheck = registryKey[0]

Categories

Resources