Hide console window for subprocesses on Windows
This commit is contained in:
parent
fa462f885d
commit
05f4a59b66
@ -1,7 +1,9 @@
|
|||||||
import os, glob, subprocess, threading
|
import os, threading
|
||||||
|
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
|
|
||||||
|
|
||||||
class BaseInfo:
|
class BaseInfo:
|
||||||
"""Default device metadata"""
|
"""Default device metadata"""
|
||||||
@ -39,8 +41,8 @@ class BaseInfo:
|
|||||||
def help_params(cls, executable):
|
def help_params(cls, executable):
|
||||||
try:
|
try:
|
||||||
text = subprocess.check_output([executable, '-h'], universal_newlines=True,
|
text = subprocess.check_output([executable, '-h'], universal_newlines=True,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT, env=dict(os.environ, COLUMNS='125'),
|
||||||
env=dict(os.environ, COLUMNS='125'))
|
console=False)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
text = e.output
|
text = e.output
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import subprocess, pprint, struct, shlex, sys, time
|
import pprint, struct, shlex, sys, time
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ class PowerThread(BasePowerThread):
|
|||||||
cmdline.extend(shlex.split(additional_params))
|
cmdline.extend(shlex.split(additional_params))
|
||||||
|
|
||||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||||
universal_newlines=False)
|
universal_newlines=False, console=False)
|
||||||
|
|
||||||
def parse_output(self, buf):
|
def parse_output(self, buf):
|
||||||
"""Parse one buf of output from hackrf_sweep"""
|
"""Parse one buf of output from hackrf_sweep"""
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import subprocess, pprint, shlex
|
import pprint, shlex
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ class PowerThread(BasePowerThread):
|
|||||||
cmdline.extend(shlex.split(additional_params))
|
cmdline.extend(shlex.split(additional_params))
|
||||||
|
|
||||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
universal_newlines=True, console=False)
|
||||||
|
|
||||||
def parse_output(self, line):
|
def parse_output(self, line):
|
||||||
"""Parse one line of output from rtl_power"""
|
"""Parse one line of output from rtl_power"""
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import subprocess, math, pprint, shlex
|
import math, pprint, shlex
|
||||||
|
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||||
|
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ class PowerThread(BasePowerThread):
|
|||||||
cmdline.extend(shlex.split(additional_params))
|
cmdline.extend(shlex.split(additional_params))
|
||||||
|
|
||||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
universal_newlines=True, console=False)
|
||||||
|
|
||||||
def parse_output(self, line):
|
def parse_output(self, line):
|
||||||
"""Parse one line of output from rtl_power_fftw"""
|
"""Parse one line of output from rtl_power_fftw"""
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import subprocess, pprint, shlex
|
import pprint, shlex
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ class PowerThread(BasePowerThread):
|
|||||||
cmdline.extend(shlex.split(additional_params))
|
cmdline.extend(shlex.split(additional_params))
|
||||||
|
|
||||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
universal_newlines=True, console=False)
|
||||||
|
|
||||||
def parse_output(self, line):
|
def parse_output(self, line):
|
||||||
"""Parse one line of output from rx_power"""
|
"""Parse one line of output from rx_power"""
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import os, subprocess, pprint, sys, shlex, signal
|
import os, sys, pprint, shlex, signal
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from Qt import QtCore
|
from Qt import QtCore
|
||||||
|
|
||||||
|
from qspectrumanalyzer import subprocess
|
||||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -12,20 +13,6 @@ except ImportError:
|
|||||||
print('soapy_power module not found!')
|
print('soapy_power module not found!')
|
||||||
formatter = None
|
formatter = None
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
import msvcrt
|
|
||||||
import _winapi
|
|
||||||
|
|
||||||
def _make_inheritable_handle(fd):
|
|
||||||
"""Return a duplicate of handle, which is inheritable"""
|
|
||||||
h = _winapi.DuplicateHandle(
|
|
||||||
_winapi.GetCurrentProcess(),
|
|
||||||
msvcrt.get_osfhandle(fd),
|
|
||||||
_winapi.GetCurrentProcess(), 0, 1,
|
|
||||||
_winapi.DUPLICATE_SAME_ACCESS
|
|
||||||
)
|
|
||||||
return subprocess.Handle(h)
|
|
||||||
|
|
||||||
|
|
||||||
class Info(BaseInfo):
|
class Info(BaseInfo):
|
||||||
"""soapy_power device metadata"""
|
"""soapy_power device metadata"""
|
||||||
@ -47,12 +34,12 @@ class Info(BaseInfo):
|
|||||||
def help_device(cls, executable, device):
|
def help_device(cls, executable, device):
|
||||||
try:
|
try:
|
||||||
text = subprocess.check_output([executable, '--detect'], universal_newlines=True,
|
text = subprocess.check_output([executable, '--detect'], universal_newlines=True,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL, env=dict(os.environ, COLUMNS='125'),
|
||||||
env=dict(os.environ, COLUMNS='125'))
|
console=False)
|
||||||
text += '\n'
|
text += '\n'
|
||||||
text += subprocess.check_output([executable, '--device', device, '--info'], universal_newlines=True,
|
text += subprocess.check_output([executable, '--device', device, '--info'], universal_newlines=True,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL, env=dict(os.environ, COLUMNS='125'),
|
||||||
env=dict(os.environ, COLUMNS='125'))
|
console=False)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
text = e.output
|
text = e.output
|
||||||
except OSError:
|
except OSError:
|
||||||
@ -101,7 +88,7 @@ class PowerThread(BasePowerThread):
|
|||||||
os.set_inheritable(self.pipe_write_fd, True)
|
os.set_inheritable(self.pipe_write_fd, True)
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
self.pipe_write_handle = _make_inheritable_handle(self.pipe_write_fd)
|
self.pipe_write_handle = subprocess.make_inheritable_handle(self.pipe_write_fd)
|
||||||
|
|
||||||
# Prepare soapy_power cmdline parameters
|
# Prepare soapy_power cmdline parameters
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
@ -142,7 +129,7 @@ class PowerThread(BasePowerThread):
|
|||||||
creationflags = 0
|
creationflags = 0
|
||||||
|
|
||||||
self.process = subprocess.Popen(cmdline, close_fds=False, universal_newlines=False,
|
self.process = subprocess.Popen(cmdline, close_fds=False, universal_newlines=False,
|
||||||
creationflags=creationflags)
|
creationflags=creationflags, console=False)
|
||||||
|
|
||||||
os.close(self.pipe_write_fd)
|
os.close(self.pipe_write_fd)
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
81
qspectrumanalyzer/subprocess.py
Normal file
81
qspectrumanalyzer/subprocess.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import sys, subprocess
|
||||||
|
|
||||||
|
# Basic attributes and exceptions
|
||||||
|
PIPE = subprocess.PIPE
|
||||||
|
STDOUT = subprocess.STDOUT
|
||||||
|
DEVNULL = subprocess.DEVNULL
|
||||||
|
SubprocessError = subprocess.SubprocessError
|
||||||
|
TimeoutExpired = subprocess.TimeoutExpired
|
||||||
|
CalledProcessError = subprocess.CalledProcessError
|
||||||
|
|
||||||
|
# Windows-only attributes and functions
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
import msvcrt
|
||||||
|
import _winapi
|
||||||
|
|
||||||
|
# creationflags
|
||||||
|
CREATE_NEW_CONSOLE = subprocess.CREATE_NEW_CONSOLE
|
||||||
|
CREATE_NEW_PROCESS_GROUP = subprocess.CREATE_NEW_PROCESS_GROUP
|
||||||
|
|
||||||
|
# startupinfo
|
||||||
|
STARTUPINFO = subprocess.STARTUPINFO
|
||||||
|
STARTF_USESTDHANDLES = subprocess.STARTF_USESTDHANDLES
|
||||||
|
STARTF_USESHOWWINDOW = subprocess.STARTF_USESHOWWINDOW
|
||||||
|
SW_HIDE = subprocess.SW_HIDE
|
||||||
|
|
||||||
|
# file handles
|
||||||
|
Handle = subprocess.Handle
|
||||||
|
STD_INPUT_HANDLE = subprocess.STD_INPUT_HANDLE
|
||||||
|
STD_OUTPUT_HANDLE = subprocess.STD_OUTPUT_HANDLE
|
||||||
|
STD_ERROR_HANDLE = subprocess.STD_ERROR_HANDLE
|
||||||
|
|
||||||
|
def make_inheritable_handle(fd):
|
||||||
|
"""Create inheritable duplicate of handle from file descriptor"""
|
||||||
|
h = _winapi.DuplicateHandle(
|
||||||
|
_winapi.GetCurrentProcess(),
|
||||||
|
msvcrt.get_osfhandle(fd),
|
||||||
|
_winapi.GetCurrentProcess(), 0, 1,
|
||||||
|
_winapi.DUPLICATE_SAME_ACCESS
|
||||||
|
)
|
||||||
|
return subprocess.Handle(h)
|
||||||
|
|
||||||
|
|
||||||
|
def hide_console_window(startupinfo=None):
|
||||||
|
"""Returns altered startupinfo to hide console window on Windows"""
|
||||||
|
if sys.platform != 'win32':
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not startupinfo:
|
||||||
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
|
||||||
|
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||||
|
return startupinfo
|
||||||
|
|
||||||
|
|
||||||
|
class Popen(subprocess.Popen):
|
||||||
|
"""subprocess.Popen with ability to hide console window on Windows"""
|
||||||
|
def __init__(self, *pargs, console=True, **kwargs):
|
||||||
|
if not console:
|
||||||
|
kwargs['startupinfo'] = hide_console_window(kwargs.get('startupinfo'))
|
||||||
|
super().__init__(*pargs, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def call(*pargs, console=True, **kwargs):
|
||||||
|
"""subprocess.call with ability to hide console window on Windows"""
|
||||||
|
if not console:
|
||||||
|
kwargs['startupinfo'] = hide_console_window(kwargs.get('startupinfo'))
|
||||||
|
return subprocess.call(*pargs, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def check_call(*pargs, console=True, **kwargs):
|
||||||
|
"""subprocess.check_call with ability to hide console window on Windows"""
|
||||||
|
if not console:
|
||||||
|
kwargs['startupinfo'] = hide_console_window(kwargs.get('startupinfo'))
|
||||||
|
return subprocess.check_call(*pargs, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def check_output(*pargs, console=True, **kwargs):
|
||||||
|
"""subprocess.check_output with ability to hide console window on Windows"""
|
||||||
|
if not console:
|
||||||
|
kwargs['startupinfo'] = hide_console_window(kwargs.get('startupinfo'))
|
||||||
|
return subprocess.check_output(*pargs, **kwargs)
|
Loading…
Reference in New Issue
Block a user