Guido van Rossum | 03dea6d | 1996-09-03 18:19:12 +0000 | [diff] [blame] | 1 | """Setup script for Windows NT 3.5 and Windows 95. |
Guido van Rossum | f71f613 | 1996-09-03 15:08:36 +0000 | [diff] [blame] | 2 | |
| 3 | Run this with the current directory set to the Python ``root''. |
| 4 | """ |
| 5 | |
| 6 | import sys |
| 7 | import strop |
| 8 | |
| 9 | del sys.path[1:] |
| 10 | |
| 11 | try: |
| 12 | import nt |
| 13 | except ImportError: |
| 14 | print "This script should only be run on a Windows (NT or '95) system." |
| 15 | sys.exit(1) |
| 16 | |
| 17 | try: |
| 18 | sys.winver |
| 19 | print "This Python version appears to be", sys.winver |
| 20 | except NameError: |
| 21 | print "Huh? sys.winver is not defined!" |
| 22 | sys.exit(1) |
| 23 | |
| 24 | # Try to import a common module that *should* work. |
| 25 | print "Looking for Python root directory..." |
| 26 | while 1: |
| 27 | pwd = nt.getcwd() |
| 28 | ##print "Could it be", `pwd`, "?" |
| 29 | try: |
| 30 | open("Lib\\os.py").close() |
| 31 | ##print "It appears so." |
| 32 | break |
| 33 | except IOError: |
| 34 | ##print "Hm, it doesn't appear to be. Try the parent directory." |
| 35 | try: |
| 36 | opwd = pwd |
| 37 | nt.chdir("..") |
| 38 | pwd = nt.getcwd() |
| 39 | if opwd == pwd: |
| 40 | ##print "Seems like we're in the root already." |
| 41 | raise nt.error |
| 42 | except nt.error: |
| 43 | ##print "Can't chdir to the parent -- we're stuck." |
| 44 | pass |
| 45 | else: |
| 46 | ##print "Try again one level higher." |
| 47 | continue |
| 48 | print "Hey, would you like to help?" |
| 49 | print "Please enter the pathname of the Python root." |
| 50 | while 1: |
| 51 | try: |
| 52 | dirname = raw_input("Python root: ") |
| 53 | except EOFError: |
| 54 | print "OK, I give up." |
| 55 | sys.exit(1) |
| 56 | if not dirname: |
| 57 | continue |
| 58 | try: |
| 59 | nt.chdir(dirname) |
| 60 | except nt.error: |
| 61 | print "That directory doesn't seem to exist." |
| 62 | print "Please try again." |
| 63 | else: |
| 64 | break |
| 65 | pwd = nt.getcwd() |
| 66 | print "Python root directory is", pwd |
| 67 | sys.path[1:] = [".\\Lib", ".\\Lib\win", ".\\Bin", ".\\vc40"] |
| 68 | |
| 69 | # Now we should be in a position to import win32api and win32con |
| 70 | |
| 71 | try: |
| 72 | import win32api |
| 73 | except ImportError: |
| 74 | print "Blech. We *still* can't import win32api." |
| 75 | print "Giving up." |
| 76 | sys.exit(1) |
| 77 | try: |
| 78 | import win32con |
| 79 | except ImportError: |
| 80 | print "Beh. We have win32api but not win32con." |
| 81 | print "Making do with a dummy." |
| 82 | class win32con: |
| 83 | REG_NOTIFY_CHANGE_ATTRIBUTES = 0x00000002L |
| 84 | REG_NOTIFY_CHANGE_SECURITY = 0x00000008L |
| 85 | REG_RESOURCE_REQUIREMENTS_LIST = 10 |
| 86 | REG_NONE = 0 |
| 87 | REG_SZ = 1 |
| 88 | REG_EXPAND_SZ = 2 |
| 89 | REG_BINARY = 3 |
| 90 | REG_DWORD = 4 |
| 91 | REG_DWORD_LITTLE_ENDIAN = 4 |
| 92 | REG_DWORD_BIG_ENDIAN = 5 |
| 93 | REG_LINK = 6 |
| 94 | REG_MULTI_SZ = 7 |
| 95 | REG_RESOURCE_LIST = 8 |
| 96 | REG_FULL_RESOURCE_DESCRIPTOR = 9 |
| 97 | HKEY_CLASSES_ROOT = 0x80000000 |
| 98 | HKEY_CURRENT_USER = 0x80000001 |
| 99 | HKEY_LOCAL_MACHINE = 0x80000002 |
| 100 | HKEY_USERS = 0x80000003 |
| 101 | HKEY_PERFORMANCE_DATA = 0x80000004 |
| 102 | HKEY_PERFORMANCE_TEXT = 0x80000050 |
| 103 | HKEY_PERFORMANCE_NLSTEXT = 0x80000060 |
| 104 | |
| 105 | |
| 106 | def listtree(handle, level=0): |
| 107 | i = 0 |
| 108 | while 1: |
| 109 | try: |
| 110 | key = win32api.RegEnumKey(handle, i) |
| 111 | except win32api.error: |
| 112 | break |
| 113 | try: |
| 114 | value = win32api.RegQueryValue(handle, key) |
| 115 | except win32api.error, msg: |
| 116 | try: |
| 117 | msg = msg[2] |
| 118 | except: |
| 119 | pass |
| 120 | value = "*** Error: %s" % str(msg) |
| 121 | print " "*level + "%s: %s" % (key, value) |
| 122 | subhandle = win32api.RegOpenKey(handle, key) |
| 123 | listtree(subhandle, level+1) |
| 124 | win32api.RegCloseKey(subhandle) |
| 125 | i = i+1 |
| 126 | |
| 127 | roothandle = win32con.HKEY_LOCAL_MACHINE |
| 128 | pythonkey = "Software\\Python" |
| 129 | try: |
| 130 | pythonhandle = win32api.RegOpenKey(roothandle, pythonkey) |
| 131 | except win32api.error: |
| 132 | pythonhandle = win32api.RegCreateKey(roothandle, pythonkey) |
| 133 | |
| 134 | ## listtree(pythonhandle) |
| 135 | ## try: |
| 136 | ## handle = win32api.RegOpenKey(pythonhandle, "JustTesting") |
| 137 | ## except win32api.error, msg: |
| 138 | ## try: msg = msg[2] |
| 139 | ## except: pass |
| 140 | ## ##print "Error opening, try creating instead:", msg |
| 141 | ## handle = win32api.RegCreateKey(pythonhandle, "JustTesting") |
| 142 | ## win32api.RegSetValue(handle, "test1", win32con.REG_SZ, "NO!") |
| 143 | ## win32api.RegSetValue(handle, "test2", win32con.REG_SZ, "YES!") |
| 144 | ## win32api.RegDeleteKey(handle, "test1") |
| 145 | ## win32api.RegDeleteKey(handle, "test2") |
| 146 | ## win32api.RegCloseKey(handle) |
| 147 | ## win32api.RegDeleteKey(pythonhandle, "JustTesting") |
| 148 | ## listtree(pythonhandle) |
| 149 | |
| 150 | print "Setting PythonPath..." |
| 151 | corekey = "PythonCore\\%s" % sys.winver |
| 152 | try: |
| 153 | corehandle = win32api.RegOpenKey(pythonhandle, corekey) |
| 154 | except win32api.error, msg: |
| 155 | corehandle = win32api.RegCreateKey(pythonhandle, corekey) |
| 156 | path = [] |
| 157 | pwd = nt.getcwd() |
| 158 | for i in ["Bin", |
| 159 | "Lib", |
| 160 | "Lib\\win", |
| 161 | "Lib\\tkinter", |
| 162 | "Lib\\test", |
| 163 | "Lib\\dos_8x3"]: |
| 164 | i = pwd + "\\" + i |
| 165 | path.append(i) |
| 166 | sys.path[1:] = path |
| 167 | pathvalue = strop.join(path, ";") |
| 168 | #print "Setting PythonPath to", pathvalue |
| 169 | win32api.RegSetValue(corehandle, "PythonPath", win32con.REG_SZ, pathvalue) |
| 170 | win32api.RegCloseKey(corehandle) |
| 171 | #listtree(pythonhandle) |
| 172 | win32api.RegCloseKey(pythonhandle) |
| 173 | |
Guido van Rossum | 03dea6d | 1996-09-03 18:19:12 +0000 | [diff] [blame] | 174 | print "Registering uninstaller..." |
| 175 | pwd = nt.getcwd() |
| 176 | uninstaller = '"%s\\uninstall.bat" "%s"' % (pwd, pwd) |
| 177 | uninstallkey = \ |
| 178 | "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Python"+sys.winver |
| 179 | try: |
| 180 | uihandle = win32api.RegOpenKey(roothandle, uninstallkey) |
| 181 | except win32api.error, msg: |
| 182 | uihandle = win32api.RegCreateKey(roothandle, uninstallkey) |
| 183 | win32api.RegSetValueEx(uihandle, "DisplayName", None, win32con.REG_SZ, |
| 184 | "Python "+sys.winver) |
| 185 | win32api.RegSetValueEx(uihandle, "UninstallString", None, win32con.REG_SZ, |
| 186 | uninstaller) |
| 187 | win32api.RegCloseKey(uihandle) |
| 188 | |
Guido van Rossum | f71f613 | 1996-09-03 15:08:36 +0000 | [diff] [blame] | 189 | print "Registering Python Interpreter as shell for *.py files..." |
| 190 | pwd = nt.getcwd() |
Guido van Rossum | 03dea6d | 1996-09-03 18:19:12 +0000 | [diff] [blame] | 191 | interpreter = '"%s\\Bin\\python.exe" -i "%%1"' % pwd |
Guido van Rossum | f71f613 | 1996-09-03 15:08:36 +0000 | [diff] [blame] | 192 | print "Interpreter command is", interpreter |
| 193 | root = win32con.HKEY_CLASSES_ROOT |
| 194 | sz = win32con.REG_SZ |
| 195 | win32api.RegSetValue(root, ".py", sz, "Python.Script") |
| 196 | win32api.RegSetValue(root , "Python.Script", sz, "Python Script") |
| 197 | win32api.RegSetValue(root , "Python.Script\\Shell\\Open\\Command", sz, |
| 198 | interpreter) |
| 199 | |
| 200 | import compileall |
| 201 | print "Compiling all library modules..." |
| 202 | compileall.main() |
| 203 | |
| 204 | print "Installation complete." |
| 205 | |
| 206 | envkeys = map(strop.upper, nt.environ.keys()) |
| 207 | if 'PYTHONPATH' in envkeys: |
| 208 | print """ |
| 209 | ********************************************************************** |
| 210 | WARNING! |
| 211 | You have set the environment variable PYTHONPATH. |
| 212 | This will override the default Python module search path |
| 213 | and probably cause you to use an old or broken Python installation. |
| 214 | Go into your control panel *now* and delete PYTHONPATH! |
| 215 | ********************************************************************** |
| 216 | """ |
| 217 | |
| 218 | raw_input("Press Enter to exit: ") |
| 219 | sys.exit(0) |
| 220 | |
| 221 | |
| 222 | registry_doc = """Summary of the Win32 API Registry interfaces. |
| 223 | |
| 224 | Concepts: |
| 225 | A _directory_ is a collection of key/value pairs. |
| 226 | You need a _handle_ for a directory to do anything with it. |
| 227 | There are some predefined keys, e.g. HKEY_LOCAL_MACHINE. |
| 228 | A _key_ is an ASCII string; NT file system conventions apply. |
| 229 | A _value_ has a type and some data; there are predefined types |
| 230 | (e.g. REG_SZ is a string, REG_DWORD is a 4-byte integer). |
| 231 | There's some fishiness in that in fact multiple, named values |
| 232 | can appear under each key, but this seems little used (in this |
| 233 | case, the value is best seen as a structured value). |
| 234 | A key can also refer to a _subdirectory_. In this case the |
| 235 | associated value is typically empty. To get a handle for a |
| 236 | subdirectory, use RegOpenKey(handle, key). The key can also |
| 237 | be a backslash-separated path, so you can go directly from one of |
| 238 | the predefined keys to the directory you are interested in. |
| 239 | |
| 240 | Most common functions: |
| 241 | RegOpenKey(handle, keypath) -> handle |
| 242 | Get a handle for an existing subdirectory |
| 243 | RegCreateKey(handle, keypath) -> handle |
| 244 | Get a handle for a new subdirectory |
Guido van Rossum | 03dea6d | 1996-09-03 18:19:12 +0000 | [diff] [blame] | 245 | RegDeleteKey(handle, key) |
| 246 | Delete the given subdirectory -- must be empty |
Guido van Rossum | f71f613 | 1996-09-03 15:08:36 +0000 | [diff] [blame] | 247 | RegCloseKey(handle) |
| 248 | Close a handle |
| 249 | RegGetValue(handle, subkey) -> string |
| 250 | Get the (unnamed) value stored as key in handle |
| 251 | RegSetValue(handle, subkey, type, value) |
| 252 | Set the (unnamed) value stored as key in handle, with given |
| 253 | type; type should be REG_SZ |
| 254 | RegSetValueEx(handle, name, reserved, type, value) |
| 255 | Set the value with given name to the given type and value; |
| 256 | currently reserved is ignored and type should be REG_SZ |
| 257 | |
| 258 | Functions to list directory contents (start counting at 0, fail if done): |
| 259 | RegEnumKey(handle, i) |
| 260 | Return the i'th subkey |
| 261 | RegEnumValue(handle, i) |
| 262 | Return the i'th name and value |
| 263 | |
| 264 | Lesser used functions: |
| 265 | RegFlushKey(handle) |
| 266 | Flush the changes to the handle to disk (like Unix sync()) |
| 267 | RegSaveKey(handle, filename, reserved) |
| 268 | Save the contents to a disk file (broken?!) |
| 269 | RegLoadKey(handle, keypath, filename) |
| 270 | Load the contents from a disk file (lots of restrictions!) |
| 271 | """ |