7 | 7 |
import select
|
8 | 8 |
import six
|
9 | 9 |
import subprocess
|
|
10 |
import sys
|
10 | 11 |
import time
|
11 | 12 |
import timeit
|
12 | 13 |
import warnings
|
|
221 | 222 |
|
222 | 223 |
def run(command, timeout=None, debug=False, stdin=None, print_stdout=True,
|
223 | 224 |
print_stderr=True, callback_stdout=None, callback_stderr=None,
|
224 | |
environment=None, environment_override=None):
|
|
225 |
environment=None, environment_override=None, win32resolve=True):
|
225 | 226 |
'''Run an external process.
|
226 | 227 |
|
227 | 228 |
:param array command: Command line to be run, specified as array.
|
|
237 | 238 |
:param dict environment: The full execution environment for the command.
|
238 | 239 |
:param dict environment_override: Change environment variables from the
|
239 | 240 |
current values for command execution.
|
|
241 |
:param win32resolve: If on Windows, find the appropriate executable first.
|
|
242 |
This allows running of .bat, .cmd, etc. files without
|
|
243 |
explicitly specifying their extension.
|
240 | 244 |
:return: A dictionary containing stdout, stderr, runtime, exitcode,
|
241 | 245 |
and more.
|
242 | 246 |
'''
|
|
260 | 264 |
if environment_override:
|
261 | 265 |
env = copy.copy(env)
|
262 | 266 |
env.update(environment_override)
|
|
267 |
|
|
268 |
if win32resolve and sys.platform == 'win32':
|
|
269 |
try:
|
|
270 |
import win32api
|
|
271 |
_, found_executable = win32api.FindExecutable(command[0])
|
|
272 |
logger.debug("Resolved %s as %s", command[0], found_executable)
|
|
273 |
command[0] = found_executable
|
|
274 |
except ImportError:
|
|
275 |
logger.warn("Could not resolve executable name: package win32api missing")
|
|
276 |
except Exception as e:
|
|
277 |
if not hasattr(e, 'winerror'): raise
|
|
278 |
logger.warn("Error trying to resolve the executable: %s", getattr(e, 'strerror', str(e)))
|
263 | 279 |
|
264 | 280 |
p = subprocess.Popen(command, shell=False, stdin=stdin_pipe, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
265 | 281 |
|