~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

  • Committer: Martin Pool
  • Date: 2007-06-21 04:27:47 UTC
  • mto: This revision was merged to the branch mainline in revision 2551.
  • Revision ID: mbp@sourcefrog.net-20070621042747-e3g0tdn8if750mv5
More commit specs

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
    else:
65
65
        create_buffer = ctypes.create_unicode_buffer
66
66
        suffix = 'W'
67
 
try:
68
 
    import win32file
69
 
    has_win32file = True
70
 
except ImportError:
71
 
    has_win32file = False
72
 
try:
73
 
    import win32api
74
 
    has_win32api = True
75
 
except ImportError:
76
 
    has_win32api = False
77
67
 
78
68
 
79
69
# Special Win32 API constants
179
169
    # at least return windows root directory
180
170
    windir = os.environ.get('windir')
181
171
    if windir:
182
 
        return os.path.splitdrive(windir)[0] + '/'
 
172
        return os.path.splitdrive(windir) + '/'
183
173
    # otherwise C:\ is good enough for 98% users
184
174
    return 'C:/'
185
175
 
207
197
    return os.environ.get('USERNAME', None)
208
198
 
209
199
 
210
 
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
211
 
# computer or the cluster associated with the local computer."
212
 
_WIN32_ComputerNameDnsHostname = 1
213
 
 
214
200
def get_host_name():
215
201
    """Return host machine name.
216
202
    If name cannot be obtained return None.
217
203
 
218
 
    :return: A unicode string representing the host name. On win98, this may be
219
 
        a plain string as win32 api doesn't support unicode.
 
204
    Returned value can be unicode or plain sring.
 
205
    To convert plain string to unicode use
 
206
    s.decode(bzrlib.user_encoding)
220
207
    """
221
 
    if has_win32api:
222
 
        try:
223
 
            return win32api.GetComputerNameEx(_WIN32_ComputerNameDnsHostname)
224
 
        except (NotImplementedError, win32api.error):
225
 
            # NotImplemented will happen on win9x...
226
 
            pass
227
208
    if has_ctypes:
228
209
        try:
229
210
            kernel32 = ctypes.windll.kernel32
 
211
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix)
230
212
        except AttributeError:
231
 
            pass # Missing the module we need
 
213
            pass
232
214
        else:
233
215
            buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
234
216
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
235
 
 
236
 
            # Try GetComputerNameEx which gives a proper Unicode hostname
237
 
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
238
 
                                        None)
239
 
            if (GetComputerNameEx is not None
240
 
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
241
 
                                      buf, ctypes.byref(n))):
242
 
                return buf.value
243
 
 
244
 
            # Try GetComputerName in case GetComputerNameEx wasn't found
245
 
            # It returns the NETBIOS name, which isn't as good, but still ok.
246
 
            # The first GetComputerNameEx might have changed 'n', so reset it
247
 
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
248
 
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
249
 
                                      None)
250
 
            if (GetComputerName is not None
251
 
                and GetComputerName(buf, ctypes.byref(n))):
252
 
                return buf.value
253
 
    # otherwise try env variables, which will be 'mbcs' encoded
254
 
    # on Windows (Python doesn't expose the native win32 unicode environment)
255
 
    # According to this:
256
 
    # http://msdn.microsoft.com/en-us/library/aa246807.aspx
257
 
    # environment variables should always be encoded in 'mbcs'.
258
 
    try:
259
 
        return os.environ['COMPUTERNAME'].decode("mbcs")
260
 
    except KeyError:
261
 
        return None
 
217
            if GetComputerName(buf, ctypes.byref(n)):
 
218
                return buf.value
 
219
    # otherwise try env variables
 
220
    return os.environ.get('COMPUTERNAME', None)
262
221
 
263
222
 
264
223
def _ensure_unicode(s):
266
225
        import bzrlib
267
226
        s = s.decode(bzrlib.user_encoding)
268
227
    return s
269
 
 
 
228
    
270
229
 
271
230
def get_appdata_location_unicode():
272
231
    return _ensure_unicode(get_appdata_location())
279
238
 
280
239
def get_host_name_unicode():
281
240
    return _ensure_unicode(get_host_name())
282
 
 
283
 
 
284
 
def _ensure_with_dir(path):
285
 
    if not os.path.split(path)[0] or path.startswith(u'*') or path.startswith(u'?'):
286
 
        return u'./' + path, True
287
 
    else:
288
 
        return path, False
289
 
    
290
 
def _undo_ensure_with_dir(path, corrected):
291
 
    if corrected:
292
 
        return path[2:]
293
 
    else:
294
 
        return path
295
 
 
296
 
 
297
 
 
298
 
def glob_expand(file_list):
299
 
    """Replacement for glob expansion by the shell.
300
 
 
301
 
    Win32's cmd.exe does not do glob expansion (eg ``*.py``), so we do our own
302
 
    here.
303
 
 
304
 
    :param file_list: A list of filenames which may include shell globs.
305
 
    :return: An expanded list of filenames.
306
 
 
307
 
    Introduced in bzrlib 0.18.
308
 
    """
309
 
    if not file_list:
310
 
        return []
311
 
    import glob
312
 
    expanded_file_list = []
313
 
    for possible_glob in file_list:
314
 
        
315
 
        # work around bugs in glob.glob()
316
 
        # - Python bug #1001604 ("glob doesn't return unicode with ...")
317
 
        # - failing expansion for */* with non-iso-8859-* chars
318
 
        possible_glob, corrected = _ensure_with_dir(possible_glob)
319
 
        glob_files = glob.glob(possible_glob)
320
 
 
321
 
        if glob_files == []:
322
 
            # special case to let the normal code path handle
323
 
            # files that do not exists
324
 
            expanded_file_list.append(
325
 
                _undo_ensure_with_dir(possible_glob, corrected))
326
 
        else:
327
 
            glob_files = [_undo_ensure_with_dir(elem, corrected) for elem in glob_files]
328
 
            expanded_file_list += glob_files
329
 
            
330
 
    return [elem.replace(u'\\', u'/') for elem in expanded_file_list] 
331
 
 
332
 
 
333
 
def get_app_path(appname):
334
 
    """Look up in Windows registry for full path to application executable.
335
 
    Typicaly, applications create subkey with their basename
336
 
    in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
337
 
 
338
 
    :param  appname:    name of application (if no filename extension
339
 
                        is specified, .exe used)
340
 
    :return:    full path to aplication executable from registry,
341
 
                or appname itself if nothing found.
342
 
    """
343
 
    import _winreg
344
 
    try:
345
 
        hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
346
 
                               r'SOFTWARE\Microsoft\Windows'
347
 
                               r'\CurrentVersion\App Paths')
348
 
    except EnvironmentError:
349
 
        return appname
350
 
 
351
 
    basename = appname
352
 
    if not os.path.splitext(basename)[1]:
353
 
        basename = appname + '.exe'
354
 
    try:
355
 
        try:
356
 
            fullpath = _winreg.QueryValue(hkey, basename)
357
 
        except WindowsError:
358
 
            fullpath = appname
359
 
    finally:
360
 
        _winreg.CloseKey(hkey)
361
 
 
362
 
    return fullpath
363
 
 
364
 
 
365
 
def set_file_attr_hidden(path):
366
 
    """Set file attributes to hidden if possible"""
367
 
    if has_win32file:
368
 
        win32file.SetFileAttributes(path, win32file.FILE_ATTRIBUTE_HIDDEN)