/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/brz_postinstall.py

  • Committer: Jelmer Vernooij
  • Date: 2020-03-22 01:35:14 UTC
  • mfrom: (7490.7.6 work)
  • mto: This revision was merged to the branch mainline in revision 7499.
  • Revision ID: jelmer@jelmer.uk-20200322013514-7vw1ntwho04rcuj3
merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, 2007, 2009, 2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""brz 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 = """Brz 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-brz                 - update start_brz.bat
 
44
    --add-path                  - add brz directory to environment PATH
 
45
    --delete-path               - delete brz directory to environment PATH
 
46
    --add-shell-menu            - add shell context menu to start brz 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
# 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
 
72
    winver = 'Windows 98'
 
73
 
 
74
 
 
75
##
 
76
# INTERNAL VARIABLES
 
77
 
 
78
(OK, ERROR) = range(2)
 
79
VERSION_FORMAT = "%-50s%s"
 
80
 
 
81
 
 
82
def main():
 
83
    import ctypes
 
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_brz = 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-brz",
 
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-brz":
 
134
                start_brz = 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 as 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
 
 
157
    brz_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
 
158
 
 
159
    if start_brz:
 
160
        fname = os.path.join(brz_dir, "start_brz.bat")
 
161
        if os.path.isfile(fname):
 
162
            with open(fname, "r") as f:
 
163
                content = f.readlines()
 
164
        else:
 
165
            content = ["brz.exe help\n"]
 
166
 
 
167
        for ix in xrange(len(content)):
 
168
            s = content[ix]
 
169
            if re.match(r'.*(?<!\\)brz\.exe([ "].*)?$',
 
170
                        s.rstrip('\r\n'),
 
171
                        re.IGNORECASE):
 
172
                content[ix] = s.replace('brz.exe',
 
173
                                        '"%s"' % os.path.join(brz_dir,
 
174
                                                              'brz.exe'))
 
175
            elif s.find(r'C:\Program Files\Breezy') != -1:
 
176
                content[ix] = s.replace(r'C:\Program Files\Breezy',
 
177
                                        brz_dir)
 
178
 
 
179
        if dry_run:
 
180
            print("*** Write file: start_brz.bat")
 
181
            print("*** File content:")
 
182
            print(''.join(content))
 
183
        else:
 
184
            with open(fname, 'w') as f:
 
185
                f.write(''.join(content))
 
186
 
 
187
    if (add_path or delete_path) and winver == 'Windows NT':
 
188
        # find appropriate registry key:
 
189
        # 1. HKLM\System\CurrentControlSet\Control\SessionManager\Environment
 
190
        # 2. HKCU\Environment
 
191
        keys = ((_winreg.HKEY_LOCAL_MACHINE, (r'System\CurrentControlSet\Control'
 
192
                                              r'\Session Manager\Environment')),
 
193
                (_winreg.HKEY_CURRENT_USER, r'Environment'),
 
194
                )
 
195
 
 
196
        hkey = None
 
197
        for key, subkey in keys:
 
198
            try:
 
199
                hkey = _winreg.OpenKey(key, subkey, 0, _winreg.KEY_ALL_ACCESS)
 
200
                try:
 
201
                    path_u, type_ = _winreg.QueryValueEx(hkey, 'Path')
 
202
                except WindowsError:
 
203
                    if key != _winreg.HKEY_CURRENT_USER:
 
204
                        _winreg.CloseKey(hkey)
 
205
                        hkey = None
 
206
                        continue
 
207
                    else:
 
208
                        path_u = u''
 
209
                        type_ = _winreg.REG_SZ
 
210
            except EnvironmentError:
 
211
                continue
 
212
            break
 
213
 
 
214
        if hkey is None:
 
215
            print("Cannot find appropriate registry key for PATH")
 
216
        else:
 
217
            path_list = [i for i in path_u.split(os.pathsep) if i != '']
 
218
            f_change = False
 
219
            for ix, item in enumerate(path_list[:]):
 
220
                if item == brz_dir:
 
221
                    if delete_path:
 
222
                        del path_list[ix]
 
223
                        f_change = True
 
224
                    elif add_path:
 
225
                        print("*** brz already in PATH")
 
226
                    break
 
227
            else:
 
228
                if add_path and not delete_path:
 
229
                    path_list.append(brz_dir.decode(user_encoding))
 
230
                    f_change = True
 
231
 
 
232
            if f_change:
 
233
                path_u = os.pathsep.join(path_list)
 
234
                if dry_run:
 
235
                    print("*** Registry key %s\\%s" % (hkey_str[key], subkey))
 
236
                    print("*** Modify PATH variable. New value:")
 
237
                    print(path_u)
 
238
                else:
 
239
                    _winreg.SetValueEx(hkey, 'Path', 0, type_, path_u)
 
240
                    _winreg.FlushKey(hkey)
 
241
 
 
242
        if hkey is not None:
 
243
            _winreg.CloseKey(hkey)
 
244
 
 
245
    if (add_path or delete_path) and winver == 'Windows 98':
 
246
        # mutating autoexec.bat
 
247
        # adding or delete string:
 
248
        # SET PATH=%PATH%;C:\PROGRA~1\Breezy
 
249
        abat = 'C:\\autoexec.bat'
 
250
        abak = 'C:\\autoexec.bak'
 
251
 
 
252
        def backup_autoexec_bat(name, backupname, dry_run):
 
253
            # backup autoexec.bat
 
254
            if os.path.isfile(name):
 
255
                if not dry_run:
 
256
                    shutil.copyfile(name, backupname)
 
257
                else:
 
258
                    print('*** backup copy of autoexec.bat created')
 
259
 
 
260
        GetShortPathName = ctypes.windll.kernel32.GetShortPathNameA
 
261
        buf = ctypes.create_string_buffer(260)
 
262
        if GetShortPathName(brz_dir, buf, 260):
 
263
            brz_dir_8_3 = buf.value
 
264
        else:
 
265
            brz_dir_8_3 = brz_dir
 
266
        pattern = 'SET PATH=%PATH%;' + brz_dir_8_3
 
267
 
 
268
        # search pattern
 
269
        with open(abat, 'r') as f:
 
270
            lines = f.readlines()
 
271
        found = False
 
272
        for i in lines:
 
273
            if i.rstrip('\r\n') == pattern:
 
274
                found = True
 
275
                break
 
276
 
 
277
        if delete_path and found:
 
278
            backup_autoexec_bat(abat, abak, dry_run)
 
279
            if not dry_run:
 
280
                with open(abat, 'w') as f:
 
281
                    for i in lines:
 
282
                        if i.rstrip('\r\n') != pattern:
 
283
                            f.write(i)
 
284
            else:
 
285
                print('*** Remove line <%s> from autoexec.bat' % pattern)
 
286
 
 
287
        elif add_path and not found:
 
288
            backup_autoexec_bat(abat, abak, dry_run)
 
289
            if not dry_run:
 
290
                with open(abat, 'a') as f:
 
291
                    f.write(pattern)
 
292
                    f.write('\n')
 
293
            else:
 
294
                print('*** Add line <%s> to autoexec.bat' % pattern)
 
295
 
 
296
    if add_shell_menu and not delete_shell_menu:
 
297
        hkey = None
 
298
        try:
 
299
            hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT,
 
300
                                     r'Folder\shell\brz')
 
301
        except EnvironmentError:
 
302
            if not silent:
 
303
                MessageBoxA(None,
 
304
                            'Unable to create registry key for context menu',
 
305
                            'EnvironmentError',
 
306
                            MB_OK | MB_ICONERROR)
 
307
 
 
308
        if hkey is not None:
 
309
            _winreg.SetValue(hkey, '', _winreg.REG_SZ, 'Brz Here')
 
310
            hkey2 = _winreg.CreateKey(hkey, 'command')
 
311
            _winreg.SetValue(hkey2, '', _winreg.REG_SZ,
 
312
                             '%s /K "%s"' % (
 
313
                                    os.environ.get('COMSPEC', '%COMSPEC%'),
 
314
                                    os.path.join(brz_dir, 'start_brz.bat')))
 
315
            _winreg.CloseKey(hkey2)
 
316
            _winreg.CloseKey(hkey)
 
317
 
 
318
    if delete_shell_menu:
 
319
        try:
 
320
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
321
                              r'Folder\shell\brz\command')
 
322
        except EnvironmentError:
 
323
            pass
 
324
 
 
325
        try:
 
326
            _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT,
 
327
                              r'Folder\shell\brz')
 
328
        except EnvironmentError:
 
329
            pass
 
330
 
 
331
    if check_mfc71:
 
332
        try:
 
333
            ctypes.windll.LoadLibrary('mfc71.dll')
 
334
        except WindowsError:
 
335
            MessageBoxA(None,
 
336
                        ("Library MFC71.DLL is not found on your system.\n"
 
337
                         "This library needed for SFTP transport.\n"
 
338
                         "If you need to work via SFTP you should download\n"
 
339
                         "this library manually and put it to directory\n"
 
340
                         "where Brz installed.\n"
 
341
                         "For detailed instructions see:\n"
 
342
                         "http://wiki.bazaar.canonical.com/BzrOnPureWindows"
 
343
                         ),
 
344
                        "Warning",
 
345
                        MB_OK | MB_ICONEXCLAMATION)
 
346
 
 
347
    return OK
 
348
 
 
349
 
 
350
if __name__ == "__main__":
 
351
    sys.exit(main())