##// END OF EJS Templates
win32: remove try-catch block of GetModuleFileNameEx (issue2480)...
Yuya Nishihara -
r12966:5f80f44d stable
parent child Browse files
Show More
@@ -1,185 +1,180 b''
1 # win32.py - utility functions that use win32 API
1 # win32.py - utility functions that use win32 API
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Utility functions that use win32 API.
8 """Utility functions that use win32 API.
9
9
10 Mark Hammond's win32all package allows better functionality on
10 Mark Hammond's win32all package allows better functionality on
11 Windows. This module overrides definitions in util.py. If not
11 Windows. This module overrides definitions in util.py. If not
12 available, import of this module will fail, and generic code will be
12 available, import of this module will fail, and generic code will be
13 used.
13 used.
14 """
14 """
15
15
16 import win32api
16 import win32api
17
17
18 import errno, os, sys, pywintypes, win32con, win32file, win32process
18 import errno, os, sys, pywintypes, win32con, win32file, win32process
19 import winerror, win32gui, win32console
19 import winerror, win32gui, win32console
20 import osutil, encoding
20 import osutil, encoding
21 from win32com.shell import shell, shellcon
21 from win32com.shell import shell, shellcon
22
22
23 def os_link(src, dst):
23 def os_link(src, dst):
24 try:
24 try:
25 win32file.CreateHardLink(dst, src)
25 win32file.CreateHardLink(dst, src)
26 except pywintypes.error:
26 except pywintypes.error:
27 raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
27 raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
28 except NotImplementedError: # Another fake error win Win98
28 except NotImplementedError: # Another fake error win Win98
29 raise OSError(errno.EINVAL, 'Hardlinking not supported')
29 raise OSError(errno.EINVAL, 'Hardlinking not supported')
30
30
31 def _getfileinfo(pathname):
31 def _getfileinfo(pathname):
32 """Return number of hardlinks for the given file."""
32 """Return number of hardlinks for the given file."""
33 try:
33 try:
34 fh = win32file.CreateFile(pathname,
34 fh = win32file.CreateFile(pathname,
35 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
35 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
36 None, win32file.OPEN_EXISTING, 0, None)
36 None, win32file.OPEN_EXISTING, 0, None)
37 except pywintypes.error:
37 except pywintypes.error:
38 raise OSError(errno.ENOENT, 'The system cannot find the file specified')
38 raise OSError(errno.ENOENT, 'The system cannot find the file specified')
39 try:
39 try:
40 return win32file.GetFileInformationByHandle(fh)
40 return win32file.GetFileInformationByHandle(fh)
41 finally:
41 finally:
42 fh.Close()
42 fh.Close()
43
43
44 def nlinks(pathname):
44 def nlinks(pathname):
45 """Return number of hardlinks for the given file."""
45 """Return number of hardlinks for the given file."""
46 return _getfileinfo(pathname)[7]
46 return _getfileinfo(pathname)[7]
47
47
48 def samefile(fpath1, fpath2):
48 def samefile(fpath1, fpath2):
49 """Returns whether fpath1 and fpath2 refer to the same file. This is only
49 """Returns whether fpath1 and fpath2 refer to the same file. This is only
50 guaranteed to work for files, not directories."""
50 guaranteed to work for files, not directories."""
51 res1 = _getfileinfo(fpath1)
51 res1 = _getfileinfo(fpath1)
52 res2 = _getfileinfo(fpath2)
52 res2 = _getfileinfo(fpath2)
53 # Index 4 is the volume serial number, and 8 and 9 contain the file ID
53 # Index 4 is the volume serial number, and 8 and 9 contain the file ID
54 return res1[4] == res2[4] and res1[8] == res2[8] and res1[9] == res2[9]
54 return res1[4] == res2[4] and res1[8] == res2[8] and res1[9] == res2[9]
55
55
56 def samedevice(fpath1, fpath2):
56 def samedevice(fpath1, fpath2):
57 """Returns whether fpath1 and fpath2 are on the same device. This is only
57 """Returns whether fpath1 and fpath2 are on the same device. This is only
58 guaranteed to work for files, not directories."""
58 guaranteed to work for files, not directories."""
59 res1 = _getfileinfo(fpath1)
59 res1 = _getfileinfo(fpath1)
60 res2 = _getfileinfo(fpath2)
60 res2 = _getfileinfo(fpath2)
61 return res1[4] == res2[4]
61 return res1[4] == res2[4]
62
62
63 def testpid(pid):
63 def testpid(pid):
64 '''return True if pid is still running or unable to
64 '''return True if pid is still running or unable to
65 determine, False otherwise'''
65 determine, False otherwise'''
66 try:
66 try:
67 handle = win32api.OpenProcess(
67 handle = win32api.OpenProcess(
68 win32con.PROCESS_QUERY_INFORMATION, False, pid)
68 win32con.PROCESS_QUERY_INFORMATION, False, pid)
69 if handle:
69 if handle:
70 status = win32process.GetExitCodeProcess(handle)
70 status = win32process.GetExitCodeProcess(handle)
71 return status == win32con.STILL_ACTIVE
71 return status == win32con.STILL_ACTIVE
72 except pywintypes.error, details:
72 except pywintypes.error, details:
73 return details[0] != winerror.ERROR_INVALID_PARAMETER
73 return details[0] != winerror.ERROR_INVALID_PARAMETER
74 return True
74 return True
75
75
76 def lookup_reg(key, valname=None, scope=None):
76 def lookup_reg(key, valname=None, scope=None):
77 ''' Look up a key/value name in the Windows registry.
77 ''' Look up a key/value name in the Windows registry.
78
78
79 valname: value name. If unspecified, the default value for the key
79 valname: value name. If unspecified, the default value for the key
80 is used.
80 is used.
81 scope: optionally specify scope for registry lookup, this can be
81 scope: optionally specify scope for registry lookup, this can be
82 a sequence of scopes to look up in order. Default (CURRENT_USER,
82 a sequence of scopes to look up in order. Default (CURRENT_USER,
83 LOCAL_MACHINE).
83 LOCAL_MACHINE).
84 '''
84 '''
85 try:
85 try:
86 from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
86 from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
87 QueryValueEx, OpenKey
87 QueryValueEx, OpenKey
88 except ImportError:
88 except ImportError:
89 return None
89 return None
90
90
91 if scope is None:
91 if scope is None:
92 scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
92 scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
93 elif not isinstance(scope, (list, tuple)):
93 elif not isinstance(scope, (list, tuple)):
94 scope = (scope,)
94 scope = (scope,)
95 for s in scope:
95 for s in scope:
96 try:
96 try:
97 val = QueryValueEx(OpenKey(s, key), valname)[0]
97 val = QueryValueEx(OpenKey(s, key), valname)[0]
98 # never let a Unicode string escape into the wild
98 # never let a Unicode string escape into the wild
99 return encoding.tolocal(val.encode('UTF-8'))
99 return encoding.tolocal(val.encode('UTF-8'))
100 except EnvironmentError:
100 except EnvironmentError:
101 pass
101 pass
102
102
103 def system_rcpath_win32():
103 def system_rcpath_win32():
104 '''return default os-specific hgrc search path'''
104 '''return default os-specific hgrc search path'''
105 proc = win32api.GetCurrentProcess()
105 filename = win32api.GetModuleFileName(0)
106 try:
107 # This will fail on windows < NT
108 filename = win32process.GetModuleFileNameEx(proc, 0)
109 except:
110 filename = win32api.GetModuleFileName(0)
111 # Use mercurial.ini found in directory with hg.exe
106 # Use mercurial.ini found in directory with hg.exe
112 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
107 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
113 if os.path.isfile(progrc):
108 if os.path.isfile(progrc):
114 return [progrc]
109 return [progrc]
115 # Use hgrc.d found in directory with hg.exe
110 # Use hgrc.d found in directory with hg.exe
116 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
111 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
117 if os.path.isdir(progrcd):
112 if os.path.isdir(progrcd):
118 rcpath = []
113 rcpath = []
119 for f, kind in osutil.listdir(progrcd):
114 for f, kind in osutil.listdir(progrcd):
120 if f.endswith('.rc'):
115 if f.endswith('.rc'):
121 rcpath.append(os.path.join(progrcd, f))
116 rcpath.append(os.path.join(progrcd, f))
122 return rcpath
117 return rcpath
123 # else look for a system rcpath in the registry
118 # else look for a system rcpath in the registry
124 try:
119 try:
125 value = win32api.RegQueryValue(
120 value = win32api.RegQueryValue(
126 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
121 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
127 rcpath = []
122 rcpath = []
128 for p in value.split(os.pathsep):
123 for p in value.split(os.pathsep):
129 if p.lower().endswith('mercurial.ini'):
124 if p.lower().endswith('mercurial.ini'):
130 rcpath.append(p)
125 rcpath.append(p)
131 elif os.path.isdir(p):
126 elif os.path.isdir(p):
132 for f, kind in osutil.listdir(p):
127 for f, kind in osutil.listdir(p):
133 if f.endswith('.rc'):
128 if f.endswith('.rc'):
134 rcpath.append(os.path.join(p, f))
129 rcpath.append(os.path.join(p, f))
135 return rcpath
130 return rcpath
136 except pywintypes.error:
131 except pywintypes.error:
137 return []
132 return []
138
133
139 def user_rcpath_win32():
134 def user_rcpath_win32():
140 '''return os-specific hgrc search path to the user dir'''
135 '''return os-specific hgrc search path to the user dir'''
141 userdir = os.path.expanduser('~')
136 userdir = os.path.expanduser('~')
142 if sys.getwindowsversion()[3] != 2 and userdir == '~':
137 if sys.getwindowsversion()[3] != 2 and userdir == '~':
143 # We are on win < nt: fetch the APPDATA directory location and use
138 # We are on win < nt: fetch the APPDATA directory location and use
144 # the parent directory as the user home dir.
139 # the parent directory as the user home dir.
145 appdir = shell.SHGetPathFromIDList(
140 appdir = shell.SHGetPathFromIDList(
146 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
141 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
147 userdir = os.path.dirname(appdir)
142 userdir = os.path.dirname(appdir)
148 return [os.path.join(userdir, 'mercurial.ini'),
143 return [os.path.join(userdir, 'mercurial.ini'),
149 os.path.join(userdir, '.hgrc')]
144 os.path.join(userdir, '.hgrc')]
150
145
151 def getuser():
146 def getuser():
152 '''return name of current user'''
147 '''return name of current user'''
153 return win32api.GetUserName()
148 return win32api.GetUserName()
154
149
155 def set_signal_handler_win32():
150 def set_signal_handler_win32():
156 """Register a termination handler for console events including
151 """Register a termination handler for console events including
157 CTRL+C. python signal handlers do not work well with socket
152 CTRL+C. python signal handlers do not work well with socket
158 operations.
153 operations.
159 """
154 """
160 def handler(event):
155 def handler(event):
161 win32process.ExitProcess(1)
156 win32process.ExitProcess(1)
162 win32api.SetConsoleCtrlHandler(handler)
157 win32api.SetConsoleCtrlHandler(handler)
163
158
164 def hidewindow():
159 def hidewindow():
165 def callback(*args, **kwargs):
160 def callback(*args, **kwargs):
166 hwnd, pid = args
161 hwnd, pid = args
167 wpid = win32process.GetWindowThreadProcessId(hwnd)[1]
162 wpid = win32process.GetWindowThreadProcessId(hwnd)[1]
168 if pid == wpid:
163 if pid == wpid:
169 win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
164 win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
170
165
171 pid = win32process.GetCurrentProcessId()
166 pid = win32process.GetCurrentProcessId()
172 win32gui.EnumWindows(callback, pid)
167 win32gui.EnumWindows(callback, pid)
173
168
174 def termwidth():
169 def termwidth():
175 try:
170 try:
176 # Query stderr to avoid problems with redirections
171 # Query stderr to avoid problems with redirections
177 screenbuf = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
172 screenbuf = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
178 try:
173 try:
179 window = screenbuf.GetConsoleScreenBufferInfo()['Window']
174 window = screenbuf.GetConsoleScreenBufferInfo()['Window']
180 width = window.Right - window.Left
175 width = window.Right - window.Left
181 return width
176 return width
182 finally:
177 finally:
183 screenbuf.Detach()
178 screenbuf.Detach()
184 except pywintypes.error:
179 except pywintypes.error:
185 return 79
180 return 79
General Comments 0
You need to be logged in to leave comments. Login now