##// END OF EJS Templates
Merge with crew-stable
Merge with crew-stable

File last commit:

r11012:81631f0c default
r11129:ee8ea635 merge default
Show More
win32.py
204 lines | 7.1 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # win32.py - utility functions that use win32 API
#
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Martin Geisler
turn some comments back into module docstrings
r8227
"""Utility functions that use win32 API.
Mark Hammond's win32all package allows better functionality on
Windows. This module overrides definitions in util.py. If not
available, import of this module will fail, and generic code will be
used.
"""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
import win32api
import errno, os, sys, pywintypes, win32con, win32file, win32process
Patrick Mezard
win32: detect console width on Windows...
r11012 import winerror, win32gui, win32console
Matt Mackall
move encoding bits from util to encoding...
r7948 import osutil, encoding
Martin Geisler
coding style: use a space after comma...
r9198 from win32com.shell import shell, shellcon
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
def os_link(src, dst):
try:
win32file.CreateHardLink(dst, src)
# CreateHardLink sometimes succeeds on mapped drives but
# following nlinks() returns 1. Check it now and bail out.
if nlinks(src) < 2:
try:
win32file.DeleteFile(dst)
except:
pass
# Fake hardlinking error
Henrik Stuart
windows: fix use of undefined exception (issue1707)...
r8951 raise OSError(errno.EINVAL, 'Hardlinking not supported')
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except pywintypes.error, details:
Henrik Stuart
windows: fix use of undefined exception (issue1707)...
r8951 raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except NotImplementedError: # Another fake error win Win98
Henrik Stuart
windows: fix use of undefined exception (issue1707)...
r8951 raise OSError(errno.EINVAL, 'Hardlinking not supported')
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Siddharth Agarwal
Add support for relinking on Windows....
r10218 def _getfileinfo(pathname):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 """Return number of hardlinks for the given file."""
try:
fh = win32file.CreateFile(pathname,
win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
None, win32file.OPEN_EXISTING, 0, None)
Patrick Mezard
win32: close file when leaving _getfileinfo()
r10219 try:
return win32file.GetFileInformationByHandle(fh)
finally:
fh.Close()
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except pywintypes.error:
Siddharth Agarwal
Add support for relinking on Windows....
r10218 return None
def nlinks(pathname):
"""Return number of hardlinks for the given file."""
res = _getfileinfo(pathname)
if res is not None:
return res[7]
else:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return os.lstat(pathname).st_nlink
Siddharth Agarwal
Add support for relinking on Windows....
r10218 def samefile(fpath1, fpath2):
"""Returns whether fpath1 and fpath2 refer to the same file. This is only
guaranteed to work for files, not directories."""
res1 = _getfileinfo(fpath1)
res2 = _getfileinfo(fpath2)
if res1 is not None and res2 is not None:
# Index 4 is the volume serial number, and 8 and 9 contain the file ID
return res1[4] == res2[4] and res1[8] == res2[8] and res1[9] == res2[9]
else:
return False
def samedevice(fpath1, fpath2):
"""Returns whether fpath1 and fpath2 are on the same device. This is only
guaranteed to work for files, not directories."""
res1 = _getfileinfo(fpath1)
res2 = _getfileinfo(fpath2)
if res1 is not None and res2 is not None:
return res1[4] == res2[4]
else:
return False
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 def testpid(pid):
'''return True if pid is still running or unable to
determine, False otherwise'''
try:
handle = win32api.OpenProcess(
win32con.PROCESS_QUERY_INFORMATION, False, pid)
if handle:
status = win32process.GetExitCodeProcess(handle)
return status == win32con.STILL_ACTIVE
except pywintypes.error, details:
return details[0] != winerror.ERROR_INVALID_PARAMETER
return True
def lookup_reg(key, valname=None, scope=None):
''' Look up a key/value name in the Windows registry.
valname: value name. If unspecified, the default value for the key
is used.
scope: optionally specify scope for registry lookup, this can be
a sequence of scopes to look up in order. Default (CURRENT_USER,
LOCAL_MACHINE).
'''
try:
from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
QueryValueEx, OpenKey
except ImportError:
return None
if scope is None:
scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
elif not isinstance(scope, (list, tuple)):
scope = (scope,)
for s in scope:
try:
val = QueryValueEx(OpenKey(s, key), valname)[0]
# never let a Unicode string escape into the wild
Matt Mackall
move encoding bits from util to encoding...
r7948 return encoding.tolocal(val.encode('UTF-8'))
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except EnvironmentError:
pass
def system_rcpath_win32():
'''return default os-specific hgrc search path'''
proc = win32api.GetCurrentProcess()
try:
# This will fail on windows < NT
filename = win32process.GetModuleFileNameEx(proc, 0)
except:
filename = win32api.GetModuleFileName(0)
# Use mercurial.ini found in directory with hg.exe
progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
if os.path.isfile(progrc):
return [progrc]
Steve Borho
win32: allow hgrc.d on Windows
r10388 # Use hgrc.d found in directory with hg.exe
progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
if os.path.isdir(progrcd):
rcpath = []
for f, kind in osutil.listdir(progrcd):
if f.endswith('.rc'):
rcpath.append(os.path.join(progrcd, f))
return rcpath
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 # else look for a system rcpath in the registry
try:
value = win32api.RegQueryValue(
win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
rcpath = []
for p in value.split(os.pathsep):
if p.lower().endswith('mercurial.ini'):
rcpath.append(p)
elif os.path.isdir(p):
for f, kind in osutil.listdir(p):
if f.endswith('.rc'):
rcpath.append(os.path.join(p, f))
return rcpath
except pywintypes.error:
return []
def user_rcpath_win32():
'''return os-specific hgrc search path to the user dir'''
userdir = os.path.expanduser('~')
if sys.getwindowsversion()[3] != 2 and userdir == '~':
# We are on win < nt: fetch the APPDATA directory location and use
# the parent directory as the user home dir.
appdir = shell.SHGetPathFromIDList(
shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
userdir = os.path.dirname(appdir)
return [os.path.join(userdir, 'mercurial.ini'),
os.path.join(userdir, '.hgrc')]
def getuser():
'''return name of current user'''
return win32api.GetUserName()
def set_signal_handler_win32():
"""Register a termination handler for console events including
CTRL+C. python signal handlers do not work well with socket
operations.
"""
def handler(event):
win32process.ExitProcess(1)
win32api.SetConsoleCtrlHandler(handler)
Patrick Mezard
cmdutil: hide child window created by win32 spawndetached()...
r10240 def hidewindow():
def callback(*args, **kwargs):
hwnd, pid = args
wpid = win32process.GetWindowThreadProcessId(hwnd)[1]
if pid == wpid:
win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
pid = win32process.GetCurrentProcessId()
win32gui.EnumWindows(callback, pid)
Patrick Mezard
win32: detect console width on Windows...
r11012
def termwidth_():
try:
# Query stderr to avoid problems with redirections
screenbuf = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
try:
window = screenbuf.GetConsoleScreenBufferInfo()['Window']
width = window.Right - window.Left
return width
finally:
screenbuf.Detach()
except pywintypes.error:
return 79