1
 
# Copyright (C) 2006, 2007, 2009, 2010 by Canonical Ltd
 
3
 
# This program is free software; you can redistribute it and/or modify
 
4
 
# it under the terms of the GNU General Public License as published by
 
5
 
# the Free Software Foundation; either version 2 of the License, or
 
6
 
# (at your option) any later version.
 
8
 
# This program is distributed in the hope that it will be useful,
 
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 
# GNU General Public License for more details.
 
13
 
# You should have received a copy of the GNU General Public License
 
14
 
# along with this program; if not, write to the Free Software
 
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 
"""bzr postinstall helper for win32 installation
 
18
 
Written by Alexander Belchenko
 
31
 
VERSION = "1.5.20070131"
 
33
 
USAGE = """Bzr postinstall helper for win32 installation
 
37
 
    -h, --help                  - help message
 
38
 
    -v, --version               - version info
 
40
 
    -n, --dry-run               - print actions rather than execute them
 
41
 
    -q, --silent                - no messages for user
 
43
 
    --start-bzr                 - update start_bzr.bat
 
44
 
    --add-path                  - add bzr directory to environment PATH
 
45
 
    --delete-path               - delete bzr directory to environment PATH
 
46
 
    --add-shell-menu            - add shell context menu to start bzr session
 
47
 
    --delete-shell-menu         - delete context menu from shell
 
48
 
    --check-mfc71               - check if MFC71.DLL present in system
 
49
 
""" % os.path.basename(sys.argv[0])
 
52
 
_major,_minor,_build,_platform,_text = sys.getwindowsversion()
 
55
 
#   The operating system platform.
 
56
 
#   This member can be one of the following values.
 
57
 
#   ==========================  ======================================
 
59
 
#   --------------------------  --------------------------------------
 
60
 
#   VER_PLATFORM_WIN32_NT       The operating system is Windows Vista,
 
61
 
#   2                           Windows Server "Longhorn",
 
62
 
#                               Windows Server 2003, Windows XP,
 
63
 
#                               Windows 2000, or Windows NT.
 
65
 
#   VER_PLATFORM_WIN32_WINDOWS  The operating system is Windows Me,
 
66
 
#   1                           Windows 98, or Windows 95.
 
67
 
#   ==========================  ======================================
 
71
 
    # don't care about real Windows name, just to force safe operations
 
78
 
(OK, ERROR) = range(2)
 
79
 
VERSION_FORMAT = "%-50s%s"
 
89
 
    user_encoding = locale.getpreferredencoding() or 'ascii'
 
93
 
    hkey_str = {_winreg.HKEY_LOCAL_MACHINE: 'HKEY_LOCAL_MACHINE',
 
94
 
                _winreg.HKEY_CURRENT_USER: 'HKEY_CURRENT_USER',
 
95
 
                _winreg.HKEY_CLASSES_ROOT: 'HKEY_CLASSES_ROOT',
 
103
 
    add_shell_menu = False
 
104
 
    delete_shell_menu = False
 
108
 
        opts, args = getopt.getopt(sys.argv[1:], "hvnq",
 
121
 
            if o in ("-h", "--help"):
 
124
 
            elif o in ("-v", "--version"):
 
125
 
                print VERSION_FORMAT % (USAGE.splitlines()[0], VERSION)
 
128
 
            elif o in ('-n', "--dry-run"):
 
130
 
            elif o in ('-q', '--silent'):
 
133
 
            elif o == "--start-bzr":
 
135
 
            elif o == "--add-path":
 
137
 
            elif o == "--delete-path":
 
139
 
            elif o == "--add-shell-menu":
 
140
 
                add_shell_menu = True
 
141
 
            elif o == "--delete-shell-menu":
 
142
 
                delete_shell_menu = True
 
143
 
            elif o == "--check-mfc71":
 
146
 
    except getopt.GetoptError, msg:
 
151
 
    # message box from Win32API
 
152
 
    MessageBoxA = ctypes.windll.user32.MessageBoxA
 
155
 
    MB_ICONEXCLAMATION = 48
 
157
 
    bzr_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
 
160
 
        fname = os.path.join(bzr_dir, "start_bzr.bat")
 
161
 
        if os.path.isfile(fname):
 
163
 
            content = f.readlines()
 
166
 
            content = ["bzr.exe help\n"]
 
168
 
        for ix in xrange(len(content)):
 
170
 
            if re.match(r'.*(?<!\\)bzr\.exe([ "].*)?$',
 
173
 
                content[ix] = s.replace('bzr.exe',
 
174
 
                                        '"%s"' % os.path.join(bzr_dir,
 
178
 
            print "*** Write file: start_bzr.bat"
 
179
 
            print "*** File content:"
 
180
 
            print ''.join(content)
 
183
 
            f.write(''.join(content))
 
186
 
    if (add_path or delete_path) and winver == 'Windows NT':
 
187
 
        # find appropriate registry key:
 
188
 
        # 1. HKLM\System\CurrentControlSet\Control\SessionManager\Environment
 
189
 
        # 2. HKCU\Environment
 
190
 
        keys = ((_winreg.HKEY_LOCAL_MACHINE, (r'System\CurrentControlSet\Control'
 
191
 
                                              r'\Session Manager\Environment')),
 
192
 
                (_winreg.HKEY_CURRENT_USER, r'Environment'),
 
196
 
        for key, subkey in keys:
 
198
 
                hkey = _winreg.OpenKey(key, subkey, 0, _winreg.KEY_ALL_ACCESS)
 
200
 
                    path_u, type_ = _winreg.QueryValueEx(hkey, 'Path')
 
202
 
                    if key != _winreg.HKEY_CURRENT_USER:
 
203
 
                        _winreg.CloseKey(hkey)
 
208
 
                        type_ = _winreg.REG_SZ
 
209
 
            except EnvironmentError:
 
214
 
            print "Cannot find appropriate registry key for PATH"
 
216
 
            path_list = [i for i in path_u.split(os.pathsep) if i != '']
 
218
 
            for ix, item in enumerate(path_list[:]):
 
224
 
                        print "*** Bzr already in PATH"
 
227
 
                if add_path and not delete_path:
 
228
 
                    path_list.append(bzr_dir.decode(user_encoding))
 
232
 
                path_u = os.pathsep.join(path_list)
 
234
 
                    print "*** Registry key %s\\%s" % (hkey_str[key], subkey)
 
235
 
                    print "*** Modify PATH variable. New value:"
 
238
 
                    _winreg.SetValueEx(hkey, 'Path', 0, type_, path_u)
 
239
 
                    _winreg.FlushKey(hkey)
 
242
 
            _winreg.CloseKey(hkey)
 
244
 
    if (add_path or delete_path) and winver == 'Windows 98':
 
245
 
        # mutating autoexec.bat
 
246
 
        # adding or delete string:
 
247
 
        # SET PATH=%PATH%;C:\PROGRA~1\Bazaar
 
248
 
        abat = 'C:\\autoexec.bat'
 
249
 
        abak = 'C:\\autoexec.bak'
 
251
 
        def backup_autoexec_bat(name, backupname, dry_run):
 
252
 
            # backup autoexec.bat
 
253
 
            if os.path.isfile(name):
 
255
 
                    shutil.copyfile(name, backupname)
 
257
 
                    print '*** backup copy of autoexec.bat created'
 
259
 
        GetShortPathName = ctypes.windll.kernel32.GetShortPathNameA
 
260
 
        buf = ctypes.create_string_buffer(260)
 
261
 
        if GetShortPathName(bzr_dir, buf, 260):
 
262
 
            bzr_dir_8_3 = buf.value
 
264
 
            bzr_dir_8_3 = bzr_dir
 
265
 
        pattern = 'SET PATH=%PATH%;' + bzr_dir_8_3
 
269
 
        lines = f.readlines()
 
273
 
            if i.rstrip('\r\n') == pattern:
 
277
 
        if delete_path and found:
 
278
 
            backup_autoexec_bat(abat, abak, dry_run)
 
282
 
                    if i.rstrip('\r\n') != pattern:
 
286
 
                print '*** Remove line <%s> from autoexec.bat' % pattern
 
288
 
        elif add_path and not found:
 
289
 
            backup_autoexec_bat(abat, abak, dry_run)
 
296
 
                print '*** Add line <%s> to autoexec.bat' % pattern
 
298
 
    if add_shell_menu and not delete_shell_menu:
 
301
 
            hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
 
303
 
        except EnvironmentError:
 
306
 
                            'Unable to create registry key for context menu',
 
308
 
                            MB_OK | MB_ICONERROR)
 
311
 
            _winreg.SetValue(hkey, '', _winreg.REG_SZ, 'Bzr Here')
 
312
 
            hkey2 = _winreg.CreateKey(hkey, 'command')
 
313
 
            _winreg.SetValue(hkey2, '', _winreg.REG_SZ,
 
315
 
                                    os.environ.get('COMSPEC', '%COMSPEC%'),
 
316
 
                                    os.path.join(bzr_dir, 'start_bzr.bat')))
 
317
 
            _winreg.CloseKey(hkey2)
 
318
 
            _winreg.CloseKey(hkey)
 
320
 
    if delete_shell_menu:
 
322
 
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
323
 
                              r'Folder\shell\bzr\command')
 
324
 
        except EnvironmentError:
 
328
 
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
330
 
        except EnvironmentError:
 
335
 
            ctypes.windll.LoadLibrary('mfc71.dll')
 
338
 
                        ("Library MFC71.DLL is not found on your system.\n"
 
339
 
                         "This library needed for SFTP transport.\n"
 
340
 
                         "If you need to work via SFTP you should download\n"
 
341
 
                         "this library manually and put it to directory\n"
 
342
 
                         "where Bzr installed.\n"
 
343
 
                         "For detailed instructions see:\n"
 
344
 
                         "http://wiki.bazaar.canonical.com/BzrOnPureWindows"
 
347
 
                        MB_OK | MB_ICONEXCLAMATION)
 
352
 
if __name__ == "__main__":