~bzr-pqm/bzr/bzr.dev

4988.10.3 by John Arbash Meinel
Merge bzr.dev 5007, resolve conflict, update NEWS
1
# Copyright (C) 2006, 2007, 2009, 2010 by Canonical Ltd
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
16
17
"""bzr postinstall helper for win32 installation
18
Written by Alexander Belchenko
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
19
20
Dependency: ctypes
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
21
"""
22
23
import os
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
24
import shutil
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
25
import sys
26
27
28
##
29
# CONSTANTS
30
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
31
VERSION = "1.5.20070131"
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
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
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
51
# Windows version
52
_major,_minor,_build,_platform,_text = sys.getwindowsversion()
2245.4.11 by Alexander Belchenko
Small fixes after John's review; added NEWS entry
53
# from MSDN:
54
# dwPlatformId
55
#   The operating system platform.
56
#   This member can be one of the following values.
57
#   ==========================  ======================================
58
#   Value                       Meaning
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.
64
#
65
#   VER_PLATFORM_WIN32_WINDOWS  The operating system is Windows Me,
66
#   1                           Windows 98, or Windows 95.
67
#   ==========================  ======================================
68
if _platform == 2:
69
    winver = 'Windows NT'
70
else:
71
    # don't care about real Windows name, just to force safe operations
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
72
    winver = 'Windows 98'
73
74
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
75
##
76
# INTERNAL VARIABLES
77
78
(OK, ERROR) = range(2)
79
VERSION_FORMAT = "%-50s%s"
80
81
82
def main():
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
83
    import ctypes
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
84
    import getopt
85
    import re
86
    import _winreg
87
88
    import locale
89
    user_encoding = locale.getpreferredencoding() or 'ascii'
90
91
    import ctypes
92
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',
96
               }
97
98
    dry_run = False
99
    silent = False
100
    start_bzr = False
101
    add_path = False
102
    delete_path = False
103
    add_shell_menu = False
104
    delete_shell_menu = False
105
    check_mfc71 = False
106
107
    try:
108
        opts, args = getopt.getopt(sys.argv[1:], "hvnq",
109
                                   ["help", "version",
110
                                    "dry-run",
111
                                    "silent",
112
                                    "start-bzr",
113
                                    "add-path",
114
                                    "delete-path",
115
                                    "add-shell-menu",
116
                                    "delete-shell-menu",
117
                                    "check-mfc71",
118
                                   ])
119
120
        for o, a in opts:
121
            if o in ("-h", "--help"):
122
                print USAGE
123
                return OK
124
            elif o in ("-v", "--version"):
125
                print VERSION_FORMAT % (USAGE.splitlines()[0], VERSION)
126
                return OK
127
128
            elif o in ('-n', "--dry-run"):
129
                dry_run = True
130
            elif o in ('-q', '--silent'):
131
                silent = True
132
133
            elif o == "--start-bzr":
134
                start_bzr = True
135
            elif o == "--add-path":
136
                add_path = True
137
            elif o == "--delete-path":
138
                delete_path = True
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":
144
                check_mfc71 = True
145
146
    except getopt.GetoptError, msg:
147
        print str(msg)
148
        print USAGE
149
        return ERROR
150
151
    # message box from Win32API
152
    MessageBoxA = ctypes.windll.user32.MessageBoxA
153
    MB_OK = 0
154
    MB_ICONERROR = 16
155
    MB_ICONEXCLAMATION = 48
156
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
157
    bzr_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
158
159
    if start_bzr:
160
        fname = os.path.join(bzr_dir, "start_bzr.bat")
161
        if os.path.isfile(fname):
162
            f = file(fname, "r")
163
            content = f.readlines()
164
            f.close()
165
        else:
166
            content = ["bzr.exe help\n"]
167
168
        for ix in xrange(len(content)):
169
            s = content[ix]
170
            if re.match(r'.*(?<!\\)bzr\.exe([ "].*)?$',
171
                        s.rstrip('\r\n'),
172
                        re.IGNORECASE):
173
                content[ix] = s.replace('bzr.exe',
174
                                        '"%s"' % os.path.join(bzr_dir,
175
                                                              'bzr.exe'))
5475.1.3 by Matthäus G. Chajdas
Remove spaces.
176
            elif s.find(r'C:\Program Files\Bazaar') != -1:
177
                content[ix] = s.replace(r'C:\Program Files\Bazaar',
178
                                        bzr_dir)
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
179
180
        if dry_run:
181
            print "*** Write file: start_bzr.bat"
182
            print "*** File content:"
183
            print ''.join(content)
184
        else:
185
            f = file(fname, 'w')
186
            f.write(''.join(content))
187
            f.close()
188
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
189
    if (add_path or delete_path) and winver == 'Windows NT':
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
190
        # find appropriate registry key:
191
        # 1. HKLM\System\CurrentControlSet\Control\SessionManager\Environment
192
        # 2. HKCU\Environment
193
        keys = ((_winreg.HKEY_LOCAL_MACHINE, (r'System\CurrentControlSet\Control'
194
                                              r'\Session Manager\Environment')),
195
                (_winreg.HKEY_CURRENT_USER, r'Environment'),
196
               )
197
198
        hkey = None
199
        for key, subkey in keys:
200
            try:
201
                hkey = _winreg.OpenKey(key, subkey, 0, _winreg.KEY_ALL_ACCESS)
202
                try:
203
                    path_u, type_ = _winreg.QueryValueEx(hkey, 'Path')
204
                except WindowsError:
205
                    if key != _winreg.HKEY_CURRENT_USER:
206
                        _winreg.CloseKey(hkey)
207
                        hkey = None
208
                        continue
209
                    else:
210
                        path_u = u''
211
                        type_ = _winreg.REG_SZ
212
            except EnvironmentError:
213
                continue
214
            break
215
216
        if hkey is None:
217
            print "Cannot find appropriate registry key for PATH"
218
        else:
219
            path_list = [i for i in path_u.split(os.pathsep) if i != '']
220
            f_change = False
221
            for ix, item in enumerate(path_list[:]):
222
                if item == bzr_dir:
223
                    if delete_path:
224
                        del path_list[ix]
225
                        f_change = True
226
                    elif add_path:
227
                        print "*** Bzr already in PATH"
228
                    break
229
            else:
230
                if add_path and not delete_path:
231
                    path_list.append(bzr_dir.decode(user_encoding))
232
                    f_change = True
233
234
            if f_change:
235
                path_u = os.pathsep.join(path_list)
236
                if dry_run:
237
                    print "*** Registry key %s\\%s" % (hkey_str[key], subkey)
238
                    print "*** Modify PATH variable. New value:"
239
                    print path_u
240
                else:
241
                    _winreg.SetValueEx(hkey, 'Path', 0, type_, path_u)
242
                    _winreg.FlushKey(hkey)
243
244
        if not hkey is None:
245
            _winreg.CloseKey(hkey)
246
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
247
    if (add_path or delete_path) and winver == 'Windows 98':
248
        # mutating autoexec.bat
249
        # adding or delete string:
250
        # SET PATH=%PATH%;C:\PROGRA~1\Bazaar
251
        abat = 'C:\\autoexec.bat'
252
        abak = 'C:\\autoexec.bak'
253
254
        def backup_autoexec_bat(name, backupname, dry_run):
255
            # backup autoexec.bat
256
            if os.path.isfile(name):
257
                if not dry_run:
258
                    shutil.copyfile(name, backupname)
259
                else:
260
                    print '*** backup copy of autoexec.bat created'
261
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
262
        GetShortPathName = ctypes.windll.kernel32.GetShortPathNameA
263
        buf = ctypes.create_string_buffer(260)
264
        if GetShortPathName(bzr_dir, buf, 260):
265
            bzr_dir_8_3 = buf.value
266
        else:
267
            bzr_dir_8_3 = bzr_dir
268
        pattern = 'SET PATH=%PATH%;' + bzr_dir_8_3
269
270
        # search pattern
271
        f = file(abat, 'r')
272
        lines = f.readlines()
273
        f.close()
274
        found = False
275
        for i in lines:
276
            if i.rstrip('\r\n') == pattern:
277
                found = True
278
                break
279
280
        if delete_path and found:
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
281
            backup_autoexec_bat(abat, abak, dry_run)
282
            if not dry_run:
283
                f = file(abat, 'w')
284
                for i in lines:
285
                    if i.rstrip('\r\n') != pattern:
286
                        f.write(i)
287
                f.close()
288
            else:
289
                print '*** Remove line <%s> from autoexec.bat' % pattern
290
                    
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
291
        elif add_path and not found:
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
292
            backup_autoexec_bat(abat, abak, dry_run)
293
            if not dry_run:
294
                f = file(abat, 'a')
295
                f.write(pattern)
296
                f.write('\n')
297
                f.close()
298
            else:
299
                print '*** Add line <%s> to autoexec.bat' % pattern
300
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
301
    if add_shell_menu and not delete_shell_menu:
302
        hkey = None
303
        try:
304
            hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
305
                                     r'Folder\shell\bzr')
306
        except EnvironmentError:
307
            if not silent:
308
                MessageBoxA(None,
309
                            'Unable to create registry key for context menu',
310
                            'EnvironmentError',
311
                            MB_OK | MB_ICONERROR)
312
313
        if not hkey is None:
314
            _winreg.SetValue(hkey, '', _winreg.REG_SZ, 'Bzr Here')
315
            hkey2 = _winreg.CreateKey(hkey, 'command')
316
            _winreg.SetValue(hkey2, '', _winreg.REG_SZ,
2245.4.7 by Alexander Belchenko
standalone installer: win98 support
317
                             '%s /K "%s"' % (
318
                                    os.environ.get('COMSPEC', '%COMSPEC%'),
2245.4.8 by Alexander Belchenko
bzr_postinstall.py: on win98 path added to autoexec.bat should have 8.3 form
319
                                    os.path.join(bzr_dir, 'start_bzr.bat')))
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
320
            _winreg.CloseKey(hkey2)
321
            _winreg.CloseKey(hkey)
322
323
    if delete_shell_menu:
324
        try:
325
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
326
                              r'Folder\shell\bzr\command')
327
        except EnvironmentError:
328
            pass
329
330
        try:
331
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
332
                              r'Folder\shell\bzr')
333
        except EnvironmentError:
334
            pass
335
336
    if check_mfc71:
337
        try:
338
            ctypes.windll.LoadLibrary('mfc71.dll')
339
        except WindowsError:
340
            MessageBoxA(None,
341
                        ("Library MFC71.DLL is not found on your system.\n"
342
                         "This library needed for SFTP transport.\n"
343
                         "If you need to work via SFTP you should download\n"
344
                         "this library manually and put it to directory\n"
345
                         "where Bzr installed.\n"
346
                         "For detailed instructions see:\n"
4988.4.2 by Martin Pool
Change url to canonical.com or wiki, plus some doc improvements in passing
347
                         "http://wiki.bazaar.canonical.com/BzrOnPureWindows"
1821.1.1 by Alexander Belchenko
win32 installer for bzr.dev.0.9
348
                        ),
349
                        "Warning",
350
                        MB_OK | MB_ICONEXCLAMATION)
351
352
    return OK
353
354
355
if __name__ == "__main__":
356
    sys.exit(main())