blob: 8da70e907c32d17d9b1780c648d9f95d6ffe0c1d [file] [log] [blame]
Paul Prescod863d8b82000-07-21 21:43:09 +00001"""
2Windows registry support.
3
4openKey( keyname )
5 open existing key object
6
7>>> key=openKey( r"HKLM\HARDWARE\DESCRIPTION\System" )
8
9createKey( keyname )
10 create a key if it doesn't already exist
11
12>>> key=createKey( r"HKLM\SOFTWARE\Python\Test" )
13
14deleteKey( keyname )
15 delete a key if it exists
16 Note: deleteKey may not be recursive on all platforms.
17
Mark Hammondabfeff72000-07-28 03:42:40 +000018>>> key=deleteKey( r"HKLM\SOFTWARE\Python\Test" )
Paul Prescod863d8b82000-07-21 21:43:09 +000019
20RemoteKey( machine, top_level_key ):
21 open a key on another machine.
22 You can use the returned key as a basis for opens, creates and deletes
23 on the other machine.
24
25>>> key=RemoteKey( "somemachine", "HKLM" )
26
27For information on the key API, open a key and look at its docstring.
28
29
30"""
31
Fred Drakeb6e54ad2000-06-30 20:31:39 +000032import _winreg
Fred Drake69218172000-06-29 16:53:06 +000033import sys
34import exceptions
35import array
36from types import *
37import string
38
39class RegType:
Paul Prescod863d8b82000-07-21 21:43:09 +000040 "Represents one of the types that can go into the registry"
Fred Drake69218172000-06-29 16:53:06 +000041 def __init__( self, msname, friendlyname ):
42 self.msname=msname
43 self.friendlyname=friendlyname
Fred Drakeb6e54ad2000-06-30 20:31:39 +000044 self.intval=getattr( _winreg, msname )
Fred Drake69218172000-06-29 16:53:06 +000045
46 def __repr__( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +000047 "Return a useful representation of the type object"
Fred Drake69218172000-06-29 16:53:06 +000048 return "<RegType %d: %s %s>" % \
49 (self.intval, self.msname, self.friendlyname )
50
51_typeConstants={
Fred Drakeb6e54ad2000-06-30 20:31:39 +000052 _winreg.REG_NONE:
Fred Drake69218172000-06-29 16:53:06 +000053 RegType( "REG_NONE", "None" ),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000054 _winreg.REG_SZ:
Fred Drake69218172000-06-29 16:53:06 +000055 RegType( "REG_SZ", "String" ),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000056 _winreg.REG_EXPAND_SZ:
Fred Drake69218172000-06-29 16:53:06 +000057 RegType("REG_EXPAND_SZ", "Expandable Template String" ),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000058 _winreg.REG_BINARY:
Fred Drake69218172000-06-29 16:53:06 +000059 RegType("REG_BINARY", "Binary Data"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000060 _winreg.REG_DWORD :
Fred Drake69218172000-06-29 16:53:06 +000061 RegType("REG_DWORD", "Integer" ),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000062# _winreg.REG_DWORD_LITTLE_ENDIAN :
Fred Drake69218172000-06-29 16:53:06 +000063# RegType("REG_DWORD_LITTLE_ENDIAN", "Integer"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000064 _winreg.REG_DWORD_BIG_ENDIAN :
Fred Drake69218172000-06-29 16:53:06 +000065 RegType("REG_DWORD_BIG_ENDIAN", "Big Endian Integer"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000066 _winreg.REG_LINK :
Fred Drake69218172000-06-29 16:53:06 +000067 RegType("REG_LINK", "Link"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000068 _winreg.REG_MULTI_SZ :
Fred Drake69218172000-06-29 16:53:06 +000069 RegType("REG_MULTI_SZ", "List of Strings"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000070 _winreg.REG_RESOURCE_LIST :
Fred Drake69218172000-06-29 16:53:06 +000071 RegType("REG_RESOURCE_LIST", "Resource List"),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000072 _winreg.REG_FULL_RESOURCE_DESCRIPTOR :
Fred Drake69218172000-06-29 16:53:06 +000073 RegType( "REG_FULL_RESOURCE_DESCRIPTOR",
74 "Full Resource Descriptor" ),
Fred Drakeb6e54ad2000-06-30 20:31:39 +000075 _winreg.REG_RESOURCE_REQUIREMENTS_LIST:
Fred Drake69218172000-06-29 16:53:06 +000076 RegType( "REG_RESOURCE_REQUIREMENTS_LIST",
77 "Resource Requirements List" )
78}
79
80regtypes={}
81for constant in _typeConstants.values():
82 regtypes[constant.msname]=constant
83
84class _DictBase:
Paul Prescod863d8b82000-07-21 21:43:09 +000085 "Base class for dictionary-type objects"
Fred Drake69218172000-06-29 16:53:06 +000086 def __init__( self, key ):
87 self.key=key
88
89 def clear( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +000090 "Clear the list of keys/data values, as in dictionaries"
Fred Drake69218172000-06-29 16:53:06 +000091 keys=list( self.keys() )
92 map( self.__delitem__, keys )
93
94 def get( self, item, defaultVal=None ):
Paul Prescod863d8b82000-07-21 21:43:09 +000095 "Get a key/value by name or index"
Fred Drake69218172000-06-29 16:53:06 +000096 try:
97 return self.__getitem__( item )
98 except (IndexError, EnvironmentError, WindowsError):
99 return defaultVal
100
101 def has_key( self, item ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000102 "Check if a key/data value with a particular name exists"
Fred Drake69218172000-06-29 16:53:06 +0000103 try:
104 self.__getitem__( item )
105 return 1
106 except (IndexError, EnvironmentError, WindowsError):
107 return 0
108
109 def keys( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000110 "Get a list of key/data value names"
Fred Drake69218172000-06-29 16:53:06 +0000111 keys=[]
112 try:
113 for i in xrange( 0, sys.maxint ):
114 keyname = self._nameFromNum( i )
115 keys.append( keyname )
116 except (IndexError, EnvironmentError, WindowsError):
117 pass
118 return keys
119
120 def values( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000121 "Get a list of key objects or data values"
Fred Drake69218172000-06-29 16:53:06 +0000122 values=[] # map() doesn't use the IndexError semantics...
123 for i in self:
124 values.append( i )
125 return values
126
127 def items( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000128 "Get pairs of keyname/key object or valuename/value data"
Fred Drake69218172000-06-29 16:53:06 +0000129 return map( None, self.keys(), self.values() )
130
131 def __len__( self ):
132 return len( self.keys() )
133
134def _getName( item, nameFromNum ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000135 "Helper function -- don't use it directly"
Fred Drake69218172000-06-29 16:53:06 +0000136 if type( item ) == IntType:
137 try:
138 keyname = nameFromNum( item )
139 except (WindowsError, EnvironmentError):
140 raise IndexError, item
141
Mark Hammondabfeff72000-07-28 03:42:40 +0000142 elif type( item ) in [StringType, UnicodeType]:
Fred Drake69218172000-06-29 16:53:06 +0000143 keyname=item
144 else:
145 raise exceptions.TypeError, \
146 "Requires integer index or string key name"
147 return keyname
148
149
150class RegValuesDict( _DictBase ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000151 "A dictionary of registry data values"
Fred Drake69218172000-06-29 16:53:06 +0000152 def _nameFromNum( self, i ):
153 return self.key._nameFromNum( i )
154
155 def __getitem__( self, item ):
156 return self.key.getValueNameDataAndType( item )
157
158 def __setitem__( self, name, val):
159 if type( val )==TupleType:
160 data, datatype=val
161 assert isinstance( datatype, RegType )
162 self.key.setValue( name, data, datatype )
163 else:
164 self.key.setValue( name, val )
165
166 def __delitem__( self, item ):
167 valname=_getName( item, self._nameFromNum )
168 self.key.deleteValue( valname )
Fred Drake69218172000-06-29 16:53:06 +0000169
170class RegKeysDict( _DictBase ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000171 "A dictionary of registry keys"
Fred Drake69218172000-06-29 16:53:06 +0000172 def _nameFromNum( self, item ):
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000173 return _winreg.EnumKey( self.key.handle, item )
Fred Drake69218172000-06-29 16:53:06 +0000174
175 def __getitem__( self, item ):
176 keyname=_getName( item, self._nameFromNum )
177 return self.key.openSubkey( keyname )
178
179 def __delitem__( self, item ):
180 keyname=_getName( item, self._nameFromNum )
181 self.key.deleteSubkey( keyname )
182
183def openKey( keyname, samFlags=None ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000184 "Open a key by name"
Fred Drake69218172000-06-29 16:53:06 +0000185 lst=string.split( keyname, "\\", 1 )
186 if len( lst )==2:
187 hivename,path=lst
188 return hives[hivename].openSubkey( path )
189 else:
190 hivename=lst[0]
191 return hives[hivename]
192
193def createKey( keyname ):
194 lst=string.split( keyname, "\\", 1 )
195 assert len( lst )==2
196 hivename,path=lst
197 return hives[hivename].createSubkey( path )
198
199def deleteKey( keyname ):
200 lst=string.split( keyname, "\\", 1 )
201 assert len( lst )==2
202 hivename,path=lst
203 return hives[hivename].deleteSubkey( path )
204
205
206class RegKey:
Paul Prescod863d8b82000-07-21 21:43:09 +0000207 "A registry key object"
208
209 def __init__( self, name, handle=None ):
210 self.name=name
211 self.handle=handle
212
Fred Drake69218172000-06-29 16:53:06 +0000213 def _nameFromNum( self, item ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000214 "internal"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000215 (name,data,datatype)=_winreg.EnumValue( self.handle, item )
Fred Drake69218172000-06-29 16:53:06 +0000216 return name
217
218 def __nonzero__(self):
Paul Prescod863d8b82000-07-21 21:43:09 +0000219 "Is the key open?"
Fred Drake69218172000-06-29 16:53:06 +0000220 if self.handle:
221 return 1
222 else:
223 return 0
224
225 def __cmp__ (self, other ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000226 "Compare two keys for equality"
Fred Drake69218172000-06-29 16:53:06 +0000227 if hasattr( other, "handle" ) and hasattr( other, "name" ):
228 return cmp( self.name, other.name )
229 else:
230 return cmp( self.handle, other )
231
Fred Drake69218172000-06-29 16:53:06 +0000232 def __repr__( self ):
233 return "<Windows RegKey: %s>"% self.name
234
235 def close(self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000236 "Close the key"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000237 return _winreg.CloseKey( self.handle )
Fred Drake69218172000-06-29 16:53:06 +0000238
239 def getSubkeyNames( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000240 "Get a list of subkey names"
Fred Drake69218172000-06-29 16:53:06 +0000241 return self.getSubkeys().keys()
242
243 def getValueNames( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000244 "Get a list of value names"
Fred Drake69218172000-06-29 16:53:06 +0000245 return self.getValues().keys()
246
247 def deleteSubkey( self, subkey ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000248 "Delete a subkey by name"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000249 return _winreg.DeleteKey( self.handle, subkey )
Fred Drake69218172000-06-29 16:53:06 +0000250
251 def deleteValue( self, valname ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000252 "Delete a value by name"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000253 return _winreg.DeleteValue( self.handle, valname )
Fred Drake69218172000-06-29 16:53:06 +0000254
255 def createSubkey( self, keyname ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000256 "Create a subkey by name"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000257 handle=_winreg.CreateKey( self.handle, keyname )
Fred Drake69218172000-06-29 16:53:06 +0000258 return RegKey( self.name+"\\"+keyname, handle)
259
260 def openSubkey( self, keyname, samFlags=None ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000261 "Open a named subkey"
Fred Drake69218172000-06-29 16:53:06 +0000262 if samFlags:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000263 handle=_winreg.OpenKey( self.handle, keyname, 0, samFlags )
Fred Drake69218172000-06-29 16:53:06 +0000264 else:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000265 handle=_winreg.OpenKey( self.handle, keyname, 0 )
Fred Drake69218172000-06-29 16:53:06 +0000266 return RegKey( self.name+"\\"+keyname, handle )
267
268 def getSubkeys( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000269 "Get a dictionary-like mapping of subkeys"
Fred Drake69218172000-06-29 16:53:06 +0000270 return RegKeysDict( self )
271
272 def getValues( self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000273 "Get a dictionary-like mapping of data values"
Fred Drake69218172000-06-29 16:53:06 +0000274 return RegValuesDict( self )
275
276 def getValueNameDataAndType( self, valname ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000277 "Get a data value's name, data and type all at one time"
Fred Drake69218172000-06-29 16:53:06 +0000278 try:
279 if type( valname )==IntType:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000280 (valname,data,datatype)=_winreg.EnumValue( self.handle, valname )
Fred Drake69218172000-06-29 16:53:06 +0000281 else:
282 keyname=_getName( valname, self._nameFromNum )
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000283 (data,datatype)=_winreg.QueryValueEx( self.handle, keyname )
Fred Drake69218172000-06-29 16:53:06 +0000284 except (WindowsError, EnvironmentError):
285 raise IndexError, valname
286
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000287 if datatype==_winreg.REG_BINARY:
Fred Drake69218172000-06-29 16:53:06 +0000288 # use arrays for binary data
289 data=array.array( 'c', data )
290
291 return (valname, data, _typeConstants[datatype] )
292
293 def getValueData( self, valname ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000294 "Get a data value's data."
Fred Drake69218172000-06-29 16:53:06 +0000295 name, data, type=self.getValueNameDataAndType( valname )
296 return data
297
298 def setValue( self, valname, data, regtype=None ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000299 "Set a data value's data (and optionally type)"
Fred Drake69218172000-06-29 16:53:06 +0000300 if regtype:
301 typeint=regtype.intval
302 else:
Mark Hammondabfeff72000-07-28 03:42:40 +0000303 if type( data ) in [StringType, UnicodeType]:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000304 typeint=_winreg.REG_SZ
Mark Hammondabfeff72000-07-28 03:42:40 +0000305 elif type( data )==ListType:
306 # XXX - _winreg currently only supports lists
307 # Also, probably should check each element is
308 # string/unicode.
309 typeint = _winreg.REG_MULTI_SZ
Fred Drake69218172000-06-29 16:53:06 +0000310 elif type( data )==IntType:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000311 typeint=_winreg.REG_DWORD
Fred Drake69218172000-06-29 16:53:06 +0000312 elif type( data )==array.ArrayType:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000313 typeint=_winreg.REG_BINARY
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000314 _winreg.SetValueEx( self.handle, valname, 0, typeint, data )
Fred Drake69218172000-06-29 16:53:06 +0000315
316 def flush(self ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000317 "Make sure that all changes are written to the registry. "
318 "Only use this if you know what you are doing. "
319 "It isn't usually needed."
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000320 _winreg.FlushKey( self.keyobbj )
Fred Drake69218172000-06-29 16:53:06 +0000321
322 def save( self, filename ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000323 "Save a key to a filename"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000324 _winreg.SaveKey( self.keyobj, filename )
Fred Drake69218172000-06-29 16:53:06 +0000325
326 def load( self, subkey, filename ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000327 "Load a key from a filename"
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000328 return _winreg.RegLoadKey( self.handle, subkey, filename )
Fred Drake69218172000-06-29 16:53:06 +0000329
330
331class RemoteKey( RegKey ):
Paul Prescod863d8b82000-07-21 21:43:09 +0000332 "Open a key on a remote machine"
Fred Drake69218172000-06-29 16:53:06 +0000333 def __init__( self, machine, topLevelKey ):
334 assert topLevelKey in _hivenames
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000335 self.handle = _winreg.ConnectRegistry( machine, parentKey )
Fred Drake69218172000-06-29 16:53:06 +0000336 self.name=r"\\%s\%s" % (machine, topLevelKey )
337
338_hivenames = ["HKEY_CLASSES_ROOT","HKEY_CURRENT_USER","HKEY_LOCAL_MACHINE",
339 "HKEY_USERS","HKEY_CURRENT_CONFIG","HKEY_DYN_DATA",
340 "HKEY_PERFORMANCE_DATA"]
341hives={}
342for name in _hivenames:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000343 hives[name]=RegKey( name, getattr( _winreg, name ) )
Fred Drake69218172000-06-29 16:53:06 +0000344hives["HKLM"]=hives["HKEY_LOCAL_MACHINE"]
345hives["HKCR"]=hives["HKEY_CLASSES_ROOT"]
346hives["HKCU"]=hives["HKEY_CURRENT_USER"]
347
348_flagnames = ["KEY_ALL_ACCESS","KEY_CREATE_LINK", "KEY_CREATE_SUB_KEY",
349 "KEY_ENUMERATE_SUB_KEYS", "KEY_EXECUTE", "KEY_NOTIFY",
350 "KEY_QUERY_VALUE", "KEY_READ", "KEY_SET_VALUE"]
351flags={}
352for name in _flagnames:
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000353 flags[name]=getattr( _winreg, name )
Fred Drake69218172000-06-29 16:53:06 +0000354
355_RegNotifyChangeKeyValueOptions=[ "REG_NOTIFY_CHANGE_ATTRIBUTES",
356 "REG_NOTIFY_CHANGE_SECURITY", "REG_NOTIFY_CHANGE_LAST_SET",
357 "REG_NOTIFY_CHANGE_NAME", "REG_LEGAL_CHANGE_FILTER" ]
358
359_RegRestoreKeyOptions=["REG_WHOLE_HIVE_VOLATILE",
360 "REG_NO_LAZY_FLUSH",
361 "REG_OPTION_VOLATILE",
362 "REG_REFRESH_HIVE",
363 "REG_OPTION_NON_VOLATILE",
364 "REG_OPTION_BACKUP_RESTORE" ]
365
366_RegCreateKeyExOptions=[
367 "REG_LEGAL_OPTION",
368 "REG_OPTION_RESERVED",
369 "REG_OPTION_VOLATILE",
370 "REG_OPTION_NON_VOLATILE",
371 "REG_OPTION_BACKUP_RESTORE",
372 "REG_CREATED_NEW_KEY",
373 "REG_OPENED_EXISTING_KEY",
374 "REG_OPTION_CREATE_LINK"]
375
Fred Drake69218172000-06-29 16:53:06 +0000376
377#unusednames=_RegNotifyChangeKeyValueOptions+_RegRestoreKeyOptions+_RegCreateKeyExOptions
378
379#typeConstantNames=map( lambda x: x.msname, typeConstants.values() )
380
381#allnames=_hivenames+_flagnames+typeConstantNames+unusednames
Fred Drakeb6e54ad2000-06-30 20:31:39 +0000382#winregnames=_winreg.__dict__.keys()
Fred Drake69218172000-06-29 16:53:06 +0000383#for name in winregnames:
384# if name not in allnames:
385# print name
386