This repository has been archived by the owner on Mar 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
regutil.py
284 lines (243 loc) · 10.7 KB
/
regutil.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# Some registry helpers.
import win32api
import win32con
import sys
import os
error = "Registry utility error"
# A .py file has a CLSID associated with it (why? - dunno!)
CLSIDPyFile = "{b51df050-06ae-11cf-ad3b-524153480001}"
RegistryIDPyFile = "Python.File" # The registry "file type" of a .py file
RegistryIDPycFile = "Python.CompiledFile" # The registry "file type" of a .pyc file
def BuildDefaultPythonKey():
"""Builds a string containing the path to the current registry key.
The Python registry key contains the Python version. This function
uses the version of the DLL used by the current process to get the
registry key currently in use.
"""
return "Software\\Python\\PythonCore\\" + sys.winver
def GetRootKey():
"""Retrieves the Registry root in use by Python.
"""
keyname = BuildDefaultPythonKey()
try:
k = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, keyname)
k.close()
return win32con.HKEY_CURRENT_USER
except win32api.error:
return win32con.HKEY_LOCAL_MACHINE
def GetRegistryDefaultValue(subkey, rootkey = None):
"""A helper to return the default value for a key in the registry.
"""
if rootkey is None: rootkey = GetRootKey()
return win32api.RegQueryValue(rootkey, subkey)
def SetRegistryDefaultValue(subKey, value, rootkey = None):
"""A helper to set the default value for a key in the registry
"""
if rootkey is None: rootkey = GetRootKey()
if type(value)==str:
typeId = win32con.REG_SZ
elif type(value)==int:
typeId = win32con.REG_DWORD
else:
raise TypeError("Value must be string or integer - was passed " + repr(value))
win32api.RegSetValue(rootkey, subKey, typeId ,value)
def GetAppPathsKey():
return "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths"
def RegisterPythonExe(exeFullPath, exeAlias = None, exeAppPath = None):
"""Register a .exe file that uses Python.
Registers the .exe with the OS. This allows the specified .exe to
be run from the command-line or start button without using the full path,
and also to setup application specific path (ie, os.environ['PATH']).
Currently the exeAppPath is not supported, so this function is general
purpose, and not specific to Python at all. Later, exeAppPath may provide
a reasonable default that is used.
exeFullPath -- The full path to the .exe
exeAlias = None -- An alias for the exe - if none, the base portion
of the filename is used.
exeAppPath -- Not supported.
"""
# Note - Dont work on win32s (but we dont care anymore!)
if exeAppPath:
raise error("Do not support exeAppPath argument currently")
if exeAlias is None:
exeAlias = os.path.basename(exeFullPath)
win32api.RegSetValue(GetRootKey(), GetAppPathsKey() + "\\" + exeAlias, win32con.REG_SZ, exeFullPath)
def GetRegisteredExe(exeAlias):
"""Get a registered .exe
"""
return win32api.RegQueryValue(GetRootKey(), GetAppPathsKey() + "\\" + exeAlias)
def UnregisterPythonExe(exeAlias):
"""Unregister a .exe file that uses Python.
"""
try:
win32api.RegDeleteKey(GetRootKey(), GetAppPathsKey() + "\\" + exeAlias)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
return
def RegisterNamedPath(name, path):
"""Register a named path - ie, a named PythonPath entry.
"""
keyStr = BuildDefaultPythonKey() + "\\PythonPath"
if name: keyStr = keyStr + "\\" + name
win32api.RegSetValue(GetRootKey(), keyStr, win32con.REG_SZ, path)
def UnregisterNamedPath(name):
"""Unregister a named path - ie, a named PythonPath entry.
"""
keyStr = BuildDefaultPythonKey() + "\\PythonPath\\" + name
try:
win32api.RegDeleteKey(GetRootKey(), keyStr)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
return
def GetRegisteredNamedPath(name):
"""Get a registered named path, or None if it doesnt exist.
"""
keyStr = BuildDefaultPythonKey() + "\\PythonPath"
if name: keyStr = keyStr + "\\" + name
try:
return win32api.RegQueryValue(GetRootKey(), keyStr)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
return None
def RegisterModule(modName, modPath):
"""Register an explicit module in the registry. This forces the Python import
mechanism to locate this module directly, without a sys.path search. Thus
a registered module need not appear in sys.path at all.
modName -- The name of the module, as used by import.
modPath -- The full path and file name of the module.
"""
try:
import os
os.stat(modPath)
except os.error:
print("Warning: Registering non-existant module %s" % modPath)
win32api.RegSetValue(GetRootKey(),
BuildDefaultPythonKey() + "\\Modules\\%s" % modName,
win32con.REG_SZ, modPath)
def UnregisterModule(modName):
"""Unregister an explicit module in the registry.
modName -- The name of the module, as used by import.
"""
try:
win32api.RegDeleteKey(GetRootKey(),
BuildDefaultPythonKey() + "\\Modules\\%s" % modName)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
def GetRegisteredHelpFile(helpDesc):
"""Given a description, return the registered entry.
"""
try:
return GetRegistryDefaultValue(BuildDefaultPythonKey() + "\\Help\\" + helpDesc)
except win32api.error:
try:
return GetRegistryDefaultValue(BuildDefaultPythonKey() + "\\Help\\" + helpDesc, win32con.HKEY_CURRENT_USER)
except win32api.error:
pass
return None
def RegisterHelpFile(helpFile, helpPath, helpDesc = None, bCheckFile = 1):
"""Register a help file in the registry.
Note that this used to support writing to the Windows Help
key, however this is no longer done, as it seems to be incompatible.
helpFile -- the base name of the help file.
helpPath -- the path to the help file
helpDesc -- A description for the help file. If None, the helpFile param is used.
bCheckFile -- A flag indicating if the file existence should be checked.
"""
if helpDesc is None: helpDesc = helpFile
fullHelpFile = os.path.join(helpPath, helpFile)
try:
if bCheckFile: os.stat(fullHelpFile)
except os.error:
raise ValueError("Help file does not exist")
# Now register with Python itself.
win32api.RegSetValue(GetRootKey(),
BuildDefaultPythonKey() + "\\Help\\%s" % helpDesc, win32con.REG_SZ, fullHelpFile)
def UnregisterHelpFile(helpFile, helpDesc = None):
"""Unregister a help file in the registry.
helpFile -- the base name of the help file.
helpDesc -- A description for the help file. If None, the helpFile param is used.
"""
key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Help", 0, win32con.KEY_ALL_ACCESS)
try:
try:
win32api.RegDeleteValue(key, helpFile)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
finally:
win32api.RegCloseKey(key)
# Now de-register with Python itself.
if helpDesc is None: helpDesc = helpFile
try:
win32api.RegDeleteKey(GetRootKey(),
BuildDefaultPythonKey() + "\\Help\\%s" % helpDesc)
except win32api.error as exc:
import winerror
if exc.winerror!=winerror.ERROR_FILE_NOT_FOUND:
raise
def RegisterCoreDLL(coredllName = None):
"""Registers the core DLL in the registry.
If no params are passed, the name of the Python DLL used in
the current process is used and registered.
"""
if coredllName is None:
coredllName = win32api.GetModuleFileName(sys.dllhandle)
# must exist!
else:
try:
os.stat(coredllName)
except os.error:
print("Warning: Registering non-existant core DLL %s" % coredllName)
hKey = win32api.RegCreateKey(GetRootKey() , BuildDefaultPythonKey())
try:
win32api.RegSetValue(hKey, "Dll", win32con.REG_SZ, coredllName)
finally:
win32api.RegCloseKey(hKey)
# Lastly, setup the current version to point to me.
win32api.RegSetValue(GetRootKey(), "Software\\Python\\PythonCore\\CurrentVersion", win32con.REG_SZ, sys.winver)
def RegisterFileExtensions(defPyIcon, defPycIcon, runCommand):
"""Register the core Python file extensions.
defPyIcon -- The default icon to use for .py files, in 'fname,offset' format.
defPycIcon -- The default icon to use for .pyc files, in 'fname,offset' format.
runCommand -- The command line to use for running .py files
"""
# Register the file extensions.
pythonFileId = RegistryIDPyFile
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , ".py", win32con.REG_SZ, pythonFileId)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , pythonFileId , win32con.REG_SZ, "Python File")
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , "%s\\CLSID" % pythonFileId , win32con.REG_SZ, CLSIDPyFile)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , "%s\\DefaultIcon" % pythonFileId, win32con.REG_SZ, defPyIcon)
base = "%s\\Shell" % RegistryIDPyFile
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\Open", win32con.REG_SZ, "Run")
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\Open\\Command", win32con.REG_SZ, runCommand)
# Register the .PYC.
pythonFileId = RegistryIDPycFile
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , ".pyc", win32con.REG_SZ, pythonFileId)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , pythonFileId , win32con.REG_SZ, "Compiled Python File")
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , "%s\\DefaultIcon" % pythonFileId, win32con.REG_SZ, defPycIcon)
base = "%s\\Shell" % pythonFileId
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\Open", win32con.REG_SZ, "Run")
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\Open\\Command", win32con.REG_SZ, runCommand)
def RegisterShellCommand(shellCommand, exeCommand, shellUserCommand = None):
# Last param for "Open" - for a .py file to be executed by the command line
# or shell execute (eg, just entering "foo.py"), the Command must be "Open",
# but you may associate a different name for the right-click menu.
# In our case, normally we have "Open=Run"
base = "%s\\Shell" % RegistryIDPyFile
if shellUserCommand:
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\%s" % (shellCommand), win32con.REG_SZ, shellUserCommand)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\%s\\Command" % (shellCommand), win32con.REG_SZ, exeCommand)
def RegisterDDECommand(shellCommand, ddeApp, ddeTopic, ddeCommand):
base = "%s\\Shell" % RegistryIDPyFile
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\%s\\ddeexec" % (shellCommand), win32con.REG_SZ, ddeCommand)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\%s\\ddeexec\\Application" % (shellCommand), win32con.REG_SZ, ddeApp)
win32api.RegSetValue(win32con.HKEY_CLASSES_ROOT , base + "\\%s\\ddeexec\\Topic" % (shellCommand), win32con.REG_SZ, ddeTopic)