6 | 6 |
import logging
|
7 | 7 |
import os
|
8 | 8 |
import select
|
|
9 |
import shutil
|
9 | 10 |
import subprocess
|
10 | 11 |
import sys
|
11 | 12 |
import time
|
|
276 | 277 |
Try and find the full path and file extension of the executable to run.
|
277 | 278 |
This is so that e.g. calls to 'somescript' will point at 'somescript.cmd'
|
278 | 279 |
without the need to set shell=True in the subprocess.
|
279 | |
If the executable contains periods it is a special case. Here the
|
280 | |
win32api call will fail to resolve the extension automatically, and it
|
281 | |
has do be done explicitly.
|
282 | 280 |
|
283 | 281 |
:param command: The command array to be run, with the first element being
|
284 | 282 |
the command with or w/o path, with or w/o extension.
|
|
286 | 284 |
correct extension. If the executable cannot be resolved for any
|
287 | 285 |
reason the original command array is returned.
|
288 | 286 |
"""
|
289 | |
try:
|
290 | |
import win32api
|
291 | |
except ImportError:
|
292 | |
if (2, 8) < sys.version_info < (3, 5):
|
293 | |
logger.info(
|
294 | |
"Resolving executable names only supported on Python 2.7 and 3.5+"
|
295 | |
)
|
296 | |
else:
|
297 | |
logger.warning(
|
298 | |
"Could not resolve executable name: package win32api missing"
|
299 | |
)
|
300 | |
return command
|
301 | |
|
302 | 287 |
if not command or not isinstance(command[0], str):
|
303 | 288 |
return command
|
304 | 289 |
|
305 | |
try:
|
306 | |
_, found_executable = win32api.FindExecutable(command[0])
|
|
290 |
found_executable = shutil.which(command[0])
|
|
291 |
if found_executable:
|
307 | 292 |
logger.debug("Resolved %s as %s", command[0], found_executable)
|
308 | |
return (found_executable,) + tuple(command[1:])
|
309 | |
except Exception as e:
|
310 | |
if not hasattr(e, "winerror"):
|
311 | |
raise
|
312 | |
# Keep this error message for later in case we fail to resolve the name
|
313 | |
logwarning = getattr(e, "strerror", str(e))
|
314 | |
|
315 | |
if "." in command[0]:
|
316 | |
# Special case. The win32api may not properly check file extensions, so
|
317 | |
# try to resolve the executable explicitly.
|
|
293 |
return (found_executable, *command[1:])
|
|
294 |
|
|
295 |
if "\\" in command[0]:
|
|
296 |
# Special case. shutil.which may not detect file extensions if a full
|
|
297 |
# path is given, so try to resolve the executable explicitly
|
318 | 298 |
for extension in os.getenv("PATHEXT").split(os.pathsep):
|
319 | |
try:
|
320 | |
_, found_executable = win32api.FindExecutable(command[0] + extension)
|
321 | |
logger.debug("Resolved %s as %s", command[0], found_executable)
|
322 | |
return (found_executable,) + tuple(command[1:])
|
323 | |
except Exception as e:
|
324 | |
if not hasattr(e, "winerror"):
|
325 | |
raise
|
326 | |
|
327 | |
logger.warning("Error trying to resolve the executable: %s", logwarning)
|
|
299 |
found_executable = shutil.which(command[0] + extension)
|
|
300 |
if found_executable:
|
|
301 |
return (found_executable, *command[1:])
|
|
302 |
|
|
303 |
logger.warning("Error trying to resolve the executable: %s", command[0])
|
328 | 304 |
return command
|
329 | 305 |
|
330 | 306 |
|