/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to tools/win32/bzr_postinstall.py

  • Committer: Alexander Belchenko
  • Date: 2007-02-01 13:32:16 UTC
  • mto: This revision was merged to the branch mainline in revision 2259.
  • Revision ID: bialix@ukr.net-20070201133216-a0wm6nuylfjgqsh7
Inno Setup script: using {cmd} macro instead of env varibale substitution (%COMSPEC%)

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
Dependency: ctypes
 
21
"""
 
22
 
 
23
import os
 
24
import shutil
 
25
import sys
 
26
 
 
27
 
 
28
##
 
29
# CONSTANTS
 
30
 
 
31
VERSION = "1.5.20070131"
 
32
 
 
33
USAGE = """Bzr postinstall helper for win32 installation
 
34
Usage: %s [options]
 
35
 
 
36
OPTIONS:
 
37
    -h, --help                  - help message
 
38
    -v, --version               - version info
 
39
 
 
40
    -n, --dry-run               - print actions rather than execute them
 
41
    -q, --silent                - no messages for user
 
42
 
 
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])
 
50
 
 
51
# Windows version
 
52
_major,_minor,_build,_platform,_text = sys.getwindowsversion()
 
53
if _platform == 0:
 
54
    raise Exception('This platform does not supported!')
 
55
elif _platform == 1:
 
56
    winver = 'Windows 98'
 
57
else:
 
58
    winver = 'Windows NT'
 
59
 
 
60
 
 
61
##
 
62
# INTERNAL VARIABLES
 
63
 
 
64
(OK, ERROR) = range(2)
 
65
VERSION_FORMAT = "%-50s%s"
 
66
 
 
67
 
 
68
def main():
 
69
    import ctypes
 
70
    import getopt
 
71
    import re
 
72
    import _winreg
 
73
 
 
74
    import locale
 
75
    user_encoding = locale.getpreferredencoding() or 'ascii'
 
76
 
 
77
    import ctypes
 
78
 
 
79
    hkey_str = {_winreg.HKEY_LOCAL_MACHINE: 'HKEY_LOCAL_MACHINE',
 
80
                _winreg.HKEY_CURRENT_USER: 'HKEY_CURRENT_USER',
 
81
                _winreg.HKEY_CLASSES_ROOT: 'HKEY_CLASSES_ROOT',
 
82
               }
 
83
 
 
84
    dry_run = False
 
85
    silent = False
 
86
    start_bzr = False
 
87
    add_path = False
 
88
    delete_path = False
 
89
    add_shell_menu = False
 
90
    delete_shell_menu = False
 
91
    check_mfc71 = False
 
92
 
 
93
    try:
 
94
        opts, args = getopt.getopt(sys.argv[1:], "hvnq",
 
95
                                   ["help", "version",
 
96
                                    "dry-run",
 
97
                                    "silent",
 
98
                                    "start-bzr",
 
99
                                    "add-path",
 
100
                                    "delete-path",
 
101
                                    "add-shell-menu",
 
102
                                    "delete-shell-menu",
 
103
                                    "check-mfc71",
 
104
                                   ])
 
105
 
 
106
        for o, a in opts:
 
107
            if o in ("-h", "--help"):
 
108
                print USAGE
 
109
                return OK
 
110
            elif o in ("-v", "--version"):
 
111
                print VERSION_FORMAT % (USAGE.splitlines()[0], VERSION)
 
112
                return OK
 
113
 
 
114
            elif o in ('-n', "--dry-run"):
 
115
                dry_run = True
 
116
            elif o in ('-q', '--silent'):
 
117
                silent = True
 
118
 
 
119
            elif o == "--start-bzr":
 
120
                start_bzr = True
 
121
            elif o == "--add-path":
 
122
                add_path = True
 
123
            elif o == "--delete-path":
 
124
                delete_path = True
 
125
            elif o == "--add-shell-menu":
 
126
                add_shell_menu = True
 
127
            elif o == "--delete-shell-menu":
 
128
                delete_shell_menu = True
 
129
            elif o == "--check-mfc71":
 
130
                check_mfc71 = True
 
131
 
 
132
    except getopt.GetoptError, msg:
 
133
        print str(msg)
 
134
        print USAGE
 
135
        return ERROR
 
136
 
 
137
    # message box from Win32API
 
138
    MessageBoxA = ctypes.windll.user32.MessageBoxA
 
139
    MB_OK = 0
 
140
    MB_ICONERROR = 16
 
141
    MB_ICONEXCLAMATION = 48
 
142
 
 
143
    bzr_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
 
144
 
 
145
    if start_bzr:
 
146
        fname = os.path.join(bzr_dir, "start_bzr.bat")
 
147
        if os.path.isfile(fname):
 
148
            f = file(fname, "r")
 
149
            content = f.readlines()
 
150
            f.close()
 
151
        else:
 
152
            content = ["bzr.exe help\n"]
 
153
 
 
154
        for ix in xrange(len(content)):
 
155
            s = content[ix]
 
156
            if re.match(r'.*(?<!\\)bzr\.exe([ "].*)?$',
 
157
                        s.rstrip('\r\n'),
 
158
                        re.IGNORECASE):
 
159
                content[ix] = s.replace('bzr.exe',
 
160
                                        '"%s"' % os.path.join(bzr_dir,
 
161
                                                              'bzr.exe'))
 
162
 
 
163
        if dry_run:
 
164
            print "*** Write file: start_bzr.bat"
 
165
            print "*** File content:"
 
166
            print ''.join(content)
 
167
        else:
 
168
            f = file(fname, 'w')
 
169
            f.write(''.join(content))
 
170
            f.close()
 
171
 
 
172
    if (add_path or delete_path) and winver == 'Windows NT':
 
173
        # find appropriate registry key:
 
174
        # 1. HKLM\System\CurrentControlSet\Control\SessionManager\Environment
 
175
        # 2. HKCU\Environment
 
176
        keys = ((_winreg.HKEY_LOCAL_MACHINE, (r'System\CurrentControlSet\Control'
 
177
                                              r'\Session Manager\Environment')),
 
178
                (_winreg.HKEY_CURRENT_USER, r'Environment'),
 
179
               )
 
180
 
 
181
        hkey = None
 
182
        for key, subkey in keys:
 
183
            try:
 
184
                hkey = _winreg.OpenKey(key, subkey, 0, _winreg.KEY_ALL_ACCESS)
 
185
                try:
 
186
                    path_u, type_ = _winreg.QueryValueEx(hkey, 'Path')
 
187
                except WindowsError:
 
188
                    if key != _winreg.HKEY_CURRENT_USER:
 
189
                        _winreg.CloseKey(hkey)
 
190
                        hkey = None
 
191
                        continue
 
192
                    else:
 
193
                        path_u = u''
 
194
                        type_ = _winreg.REG_SZ
 
195
            except EnvironmentError:
 
196
                continue
 
197
            break
 
198
 
 
199
        if hkey is None:
 
200
            print "Cannot find appropriate registry key for PATH"
 
201
        else:
 
202
            path_list = [i for i in path_u.split(os.pathsep) if i != '']
 
203
            f_change = False
 
204
            for ix, item in enumerate(path_list[:]):
 
205
                if item == bzr_dir:
 
206
                    if delete_path:
 
207
                        del path_list[ix]
 
208
                        f_change = True
 
209
                    elif add_path:
 
210
                        print "*** Bzr already in PATH"
 
211
                    break
 
212
            else:
 
213
                if add_path and not delete_path:
 
214
                    path_list.append(bzr_dir.decode(user_encoding))
 
215
                    f_change = True
 
216
 
 
217
            if f_change:
 
218
                path_u = os.pathsep.join(path_list)
 
219
                if dry_run:
 
220
                    print "*** Registry key %s\\%s" % (hkey_str[key], subkey)
 
221
                    print "*** Modify PATH variable. New value:"
 
222
                    print path_u
 
223
                else:
 
224
                    _winreg.SetValueEx(hkey, 'Path', 0, type_, path_u)
 
225
                    _winreg.FlushKey(hkey)
 
226
 
 
227
        if not hkey is None:
 
228
            _winreg.CloseKey(hkey)
 
229
 
 
230
    if (add_path or delete_path) and winver == 'Windows 98':
 
231
        # mutating autoexec.bat
 
232
        # adding or delete string:
 
233
        # SET PATH=%PATH%;C:\PROGRA~1\Bazaar
 
234
        abat = 'C:\\autoexec.bat'
 
235
        abak = 'C:\\autoexec.bak'
 
236
 
 
237
        def backup_autoexec_bat(name, backupname, dry_run):
 
238
            # backup autoexec.bat
 
239
            if os.path.isfile(name):
 
240
                if not dry_run:
 
241
                    shutil.copyfile(name, backupname)
 
242
                else:
 
243
                    print '*** backup copy of autoexec.bat created'
 
244
 
 
245
        GetShortPathName = ctypes.windll.kernel32.GetShortPathNameA
 
246
        buf = ctypes.create_string_buffer(260)
 
247
        if GetShortPathName(bzr_dir, buf, 260):
 
248
            bzr_dir_8_3 = buf.value
 
249
        else:
 
250
            bzr_dir_8_3 = bzr_dir
 
251
        pattern = 'SET PATH=%PATH%;' + bzr_dir_8_3
 
252
 
 
253
        # search pattern
 
254
        f = file(abat, 'r')
 
255
        lines = f.readlines()
 
256
        f.close()
 
257
        found = False
 
258
        for i in lines:
 
259
            if i.rstrip('\r\n') == pattern:
 
260
                found = True
 
261
                break
 
262
 
 
263
        if delete_path and found:
 
264
            backup_autoexec_bat(abat, abak, dry_run)
 
265
            if not dry_run:
 
266
                f = file(abat, 'w')
 
267
                for i in lines:
 
268
                    if i.rstrip('\r\n') != pattern:
 
269
                        f.write(i)
 
270
                f.close()
 
271
            else:
 
272
                print '*** Remove line <%s> from autoexec.bat' % pattern
 
273
                    
 
274
        elif add_path and not found:
 
275
            backup_autoexec_bat(abat, abak, dry_run)
 
276
            if not dry_run:
 
277
                f = file(abat, 'a')
 
278
                f.write(pattern)
 
279
                f.write('\n')
 
280
                f.close()
 
281
            else:
 
282
                print '*** Add line <%s> to autoexec.bat' % pattern
 
283
 
 
284
    if add_shell_menu and not delete_shell_menu:
 
285
        hkey = None
 
286
        try:
 
287
            hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
 
288
                                     r'Folder\shell\bzr')
 
289
        except EnvironmentError:
 
290
            if not silent:
 
291
                MessageBoxA(None,
 
292
                            'Unable to create registry key for context menu',
 
293
                            'EnvironmentError',
 
294
                            MB_OK | MB_ICONERROR)
 
295
 
 
296
        if not hkey is None:
 
297
            _winreg.SetValue(hkey, '', _winreg.REG_SZ, 'Bzr Here')
 
298
            hkey2 = _winreg.CreateKey(hkey, 'command')
 
299
            _winreg.SetValue(hkey2, '', _winreg.REG_SZ,
 
300
                             '%s /K "%s"' % (
 
301
                                    os.environ.get('COMSPEC', '%COMSPEC%'),
 
302
                                    os.path.join(bzr_dir, 'start_bzr.bat')))
 
303
            _winreg.CloseKey(hkey2)
 
304
            _winreg.CloseKey(hkey)
 
305
 
 
306
    if delete_shell_menu:
 
307
        try:
 
308
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
309
                              r'Folder\shell\bzr\command')
 
310
        except EnvironmentError:
 
311
            pass
 
312
 
 
313
        try:
 
314
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
315
                              r'Folder\shell\bzr')
 
316
        except EnvironmentError:
 
317
            pass
 
318
 
 
319
    if check_mfc71:
 
320
        try:
 
321
            ctypes.windll.LoadLibrary('mfc71.dll')
 
322
        except WindowsError:
 
323
            MessageBoxA(None,
 
324
                        ("Library MFC71.DLL is not found on your system.\n"
 
325
                         "This library needed for SFTP transport.\n"
 
326
                         "If you need to work via SFTP you should download\n"
 
327
                         "this library manually and put it to directory\n"
 
328
                         "where Bzr installed.\n"
 
329
                         "For detailed instructions see:\n"
 
330
                         "http://bazaar-vcs.org/BzrOnPureWindows"
 
331
                        ),
 
332
                        "Warning",
 
333
                        MB_OK | MB_ICONEXCLAMATION)
 
334
 
 
335
    return OK
 
336
 
 
337
 
 
338
if __name__ == "__main__":
 
339
    sys.exit(main())