~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/win32/bzr_postinstall.py

  • Committer: Robert Collins
  • Date: 2005-10-06 22:15:52 UTC
  • mfrom: (1185.13.2)
  • mto: This revision was merged to the branch mainline in revision 1420.
  • Revision ID: robertc@robertcollins.net-20051006221552-9b15c96fa504e0ad
mergeĀ fromĀ upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
#
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.
7
 
 
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.
12
 
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
"""bzr postinstall helper for win32 installation
18
 
Written by Alexander Belchenko
19
 
"""
20
 
 
21
 
import os
22
 
import sys
23
 
 
24
 
 
25
 
##
26
 
# CONSTANTS
27
 
 
28
 
VERSION = "1.3.20060513"
29
 
 
30
 
USAGE = """Bzr postinstall helper for win32 installation
31
 
Usage: %s [options]
32
 
 
33
 
OPTIONS:
34
 
    -h, --help                  - help message
35
 
    -v, --version               - version info
36
 
 
37
 
    -n, --dry-run               - print actions rather than execute them
38
 
    -q, --silent                - no messages for user
39
 
 
40
 
    --start-bzr                 - update start_bzr.bat
41
 
    --add-path                  - add bzr directory to environment PATH
42
 
    --delete-path               - delete bzr directory to environment PATH
43
 
    --add-shell-menu            - add shell context menu to start bzr session
44
 
    --delete-shell-menu         - delete context menu from shell
45
 
    --check-mfc71               - check if MFC71.DLL present in system
46
 
""" % os.path.basename(sys.argv[0])
47
 
 
48
 
##
49
 
# INTERNAL VARIABLES
50
 
 
51
 
(OK, ERROR) = range(2)
52
 
VERSION_FORMAT = "%-50s%s"
53
 
 
54
 
 
55
 
def main():
56
 
    import getopt
57
 
    import re
58
 
    import _winreg
59
 
 
60
 
    import locale
61
 
    user_encoding = locale.getpreferredencoding() or 'ascii'
62
 
 
63
 
    import ctypes
64
 
 
65
 
    hkey_str = {_winreg.HKEY_LOCAL_MACHINE: 'HKEY_LOCAL_MACHINE',
66
 
                _winreg.HKEY_CURRENT_USER: 'HKEY_CURRENT_USER',
67
 
                _winreg.HKEY_CLASSES_ROOT: 'HKEY_CLASSES_ROOT',
68
 
               }
69
 
 
70
 
    dry_run = False
71
 
    silent = False
72
 
    start_bzr = False
73
 
    add_path = False
74
 
    delete_path = False
75
 
    add_shell_menu = False
76
 
    delete_shell_menu = False
77
 
    check_mfc71 = False
78
 
 
79
 
    try:
80
 
        opts, args = getopt.getopt(sys.argv[1:], "hvnq",
81
 
                                   ["help", "version",
82
 
                                    "dry-run",
83
 
                                    "silent",
84
 
                                    "start-bzr",
85
 
                                    "add-path",
86
 
                                    "delete-path",
87
 
                                    "add-shell-menu",
88
 
                                    "delete-shell-menu",
89
 
                                    "check-mfc71",
90
 
                                   ])
91
 
 
92
 
        for o, a in opts:
93
 
            if o in ("-h", "--help"):
94
 
                print USAGE
95
 
                return OK
96
 
            elif o in ("-v", "--version"):
97
 
                print VERSION_FORMAT % (USAGE.splitlines()[0], VERSION)
98
 
                return OK
99
 
 
100
 
            elif o in ('-n', "--dry-run"):
101
 
                dry_run = True
102
 
            elif o in ('-q', '--silent'):
103
 
                silent = True
104
 
 
105
 
            elif o == "--start-bzr":
106
 
                start_bzr = True
107
 
            elif o == "--add-path":
108
 
                add_path = True
109
 
            elif o == "--delete-path":
110
 
                delete_path = True
111
 
            elif o == "--add-shell-menu":
112
 
                add_shell_menu = True
113
 
            elif o == "--delete-shell-menu":
114
 
                delete_shell_menu = True
115
 
            elif o == "--check-mfc71":
116
 
                check_mfc71 = True
117
 
 
118
 
    except getopt.GetoptError, msg:
119
 
        print str(msg)
120
 
        print USAGE
121
 
        return ERROR
122
 
 
123
 
    # message box from Win32API
124
 
    MessageBoxA = ctypes.windll.user32.MessageBoxA
125
 
    MB_OK = 0
126
 
    MB_ICONERROR = 16
127
 
    MB_ICONEXCLAMATION = 48
128
 
 
129
 
    bzr_dir = os.path.dirname(sys.argv[0])
130
 
 
131
 
    if start_bzr:
132
 
        fname = os.path.join(bzr_dir, "start_bzr.bat")
133
 
        if os.path.isfile(fname):
134
 
            f = file(fname, "r")
135
 
            content = f.readlines()
136
 
            f.close()
137
 
        else:
138
 
            content = ["bzr.exe help\n"]
139
 
 
140
 
        for ix in xrange(len(content)):
141
 
            s = content[ix]
142
 
            if re.match(r'.*(?<!\\)bzr\.exe([ "].*)?$',
143
 
                        s.rstrip('\r\n'),
144
 
                        re.IGNORECASE):
145
 
                content[ix] = s.replace('bzr.exe',
146
 
                                        '"%s"' % os.path.join(bzr_dir,
147
 
                                                              'bzr.exe'))
148
 
 
149
 
        if dry_run:
150
 
            print "*** Write file: start_bzr.bat"
151
 
            print "*** File content:"
152
 
            print ''.join(content)
153
 
        else:
154
 
            f = file(fname, 'w')
155
 
            f.write(''.join(content))
156
 
            f.close()
157
 
 
158
 
    if add_path or delete_path:
159
 
        # find appropriate registry key:
160
 
        # 1. HKLM\System\CurrentControlSet\Control\SessionManager\Environment
161
 
        # 2. HKCU\Environment
162
 
        keys = ((_winreg.HKEY_LOCAL_MACHINE, (r'System\CurrentControlSet\Control'
163
 
                                              r'\Session Manager\Environment')),
164
 
                (_winreg.HKEY_CURRENT_USER, r'Environment'),
165
 
               )
166
 
 
167
 
        hkey = None
168
 
        for key, subkey in keys:
169
 
            try:
170
 
                hkey = _winreg.OpenKey(key, subkey, 0, _winreg.KEY_ALL_ACCESS)
171
 
                try:
172
 
                    path_u, type_ = _winreg.QueryValueEx(hkey, 'Path')
173
 
                except WindowsError:
174
 
                    if key != _winreg.HKEY_CURRENT_USER:
175
 
                        _winreg.CloseKey(hkey)
176
 
                        hkey = None
177
 
                        continue
178
 
                    else:
179
 
                        path_u = u''
180
 
                        type_ = _winreg.REG_SZ
181
 
            except EnvironmentError:
182
 
                continue
183
 
            break
184
 
 
185
 
        if hkey is None:
186
 
            print "Cannot find appropriate registry key for PATH"
187
 
        else:
188
 
            path_list = [i for i in path_u.split(os.pathsep) if i != '']
189
 
            f_change = False
190
 
            for ix, item in enumerate(path_list[:]):
191
 
                if item == bzr_dir:
192
 
                    if delete_path:
193
 
                        del path_list[ix]
194
 
                        f_change = True
195
 
                    elif add_path:
196
 
                        print "*** Bzr already in PATH"
197
 
                    break
198
 
            else:
199
 
                if add_path and not delete_path:
200
 
                    path_list.append(bzr_dir.decode(user_encoding))
201
 
                    f_change = True
202
 
 
203
 
            if f_change:
204
 
                path_u = os.pathsep.join(path_list)
205
 
                if dry_run:
206
 
                    print "*** Registry key %s\\%s" % (hkey_str[key], subkey)
207
 
                    print "*** Modify PATH variable. New value:"
208
 
                    print path_u
209
 
                else:
210
 
                    _winreg.SetValueEx(hkey, 'Path', 0, type_, path_u)
211
 
                    _winreg.FlushKey(hkey)
212
 
 
213
 
        if not hkey is None:
214
 
            _winreg.CloseKey(hkey)
215
 
 
216
 
    if add_shell_menu and not delete_shell_menu:
217
 
        hkey = None
218
 
        try:
219
 
            hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
220
 
                                     r'Folder\shell\bzr')
221
 
        except EnvironmentError:
222
 
            if not silent:
223
 
                MessageBoxA(None,
224
 
                            'Unable to create registry key for context menu',
225
 
                            'EnvironmentError',
226
 
                            MB_OK | MB_ICONERROR)
227
 
 
228
 
        if not hkey is None:
229
 
            _winreg.SetValue(hkey, '', _winreg.REG_SZ, 'Bzr Here')
230
 
            hkey2 = _winreg.CreateKey(hkey, 'command')
231
 
            _winreg.SetValue(hkey2, '', _winreg.REG_SZ,
232
 
                             'cmd /K "%s"' % os.path.join(bzr_dir,
233
 
                                                          'start_bzr.bat'))
234
 
            _winreg.CloseKey(hkey2)
235
 
            _winreg.CloseKey(hkey)
236
 
 
237
 
    if delete_shell_menu:
238
 
        try:
239
 
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
240
 
                              r'Folder\shell\bzr\command')
241
 
        except EnvironmentError:
242
 
            pass
243
 
 
244
 
        try:
245
 
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
246
 
                              r'Folder\shell\bzr')
247
 
        except EnvironmentError:
248
 
            pass
249
 
 
250
 
    if check_mfc71:
251
 
        try:
252
 
            ctypes.windll.LoadLibrary('mfc71.dll')
253
 
        except WindowsError:
254
 
            MessageBoxA(None,
255
 
                        ("Library MFC71.DLL is not found on your system.\n"
256
 
                         "This library needed for SFTP transport.\n"
257
 
                         "If you need to work via SFTP you should download\n"
258
 
                         "this library manually and put it to directory\n"
259
 
                         "where Bzr installed.\n"
260
 
                         "For detailed instructions see:\n"
261
 
                         "http://bazaar-vcs.org/BzrOnPureWindows"
262
 
                        ),
263
 
                        "Warning",
264
 
                        MB_OK | MB_ICONEXCLAMATION)
265
 
 
266
 
    return OK
267
 
 
268
 
 
269
 
if __name__ == "__main__":
270
 
    sys.exit(main())