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 qspectrumanalyzer import subprocess
|
||||
|
||||
|
||||
class BaseInfo:
|
||||
"""Default device metadata"""
|
||||
@ -39,8 +41,8 @@ class BaseInfo:
|
||||
def help_params(cls, executable):
|
||||
try:
|
||||
text = subprocess.check_output([executable, '-h'], universal_newlines=True,
|
||||
stderr=subprocess.STDOUT,
|
||||
env=dict(os.environ, COLUMNS='125'))
|
||||
stderr=subprocess.STDOUT, env=dict(os.environ, COLUMNS='125'),
|
||||
console=False)
|
||||
except subprocess.CalledProcessError as e:
|
||||
text = e.output
|
||||
except OSError:
|
||||
|
@ -1,8 +1,9 @@
|
||||
import subprocess, pprint, struct, shlex, sys, time
|
||||
import pprint, struct, shlex, sys, time
|
||||
|
||||
import numpy as np
|
||||
from Qt import QtCore
|
||||
|
||||
from qspectrumanalyzer import subprocess
|
||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||
|
||||
|
||||
@ -108,7 +109,7 @@ class PowerThread(BasePowerThread):
|
||||
cmdline.extend(shlex.split(additional_params))
|
||||
|
||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||
universal_newlines=False)
|
||||
universal_newlines=False, console=False)
|
||||
|
||||
def parse_output(self, buf):
|
||||
"""Parse one buf of output from hackrf_sweep"""
|
||||
|
@ -1,8 +1,9 @@
|
||||
import subprocess, pprint, shlex
|
||||
import pprint, shlex
|
||||
|
||||
import numpy as np
|
||||
from Qt import QtCore
|
||||
|
||||
from qspectrumanalyzer import subprocess
|
||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||
|
||||
|
||||
@ -66,7 +67,7 @@ class PowerThread(BasePowerThread):
|
||||
cmdline.extend(shlex.split(additional_params))
|
||||
|
||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
universal_newlines=True, console=False)
|
||||
|
||||
def parse_output(self, line):
|
||||
"""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 qspectrumanalyzer import subprocess
|
||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||
|
||||
|
||||
@ -91,7 +92,7 @@ class PowerThread(BasePowerThread):
|
||||
cmdline.extend(shlex.split(additional_params))
|
||||
|
||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
universal_newlines=True, console=False)
|
||||
|
||||
def parse_output(self, line):
|
||||
"""Parse one line of output from rtl_power_fftw"""
|
||||
|
@ -1,8 +1,9 @@
|
||||
import subprocess, pprint, shlex
|
||||
import pprint, shlex
|
||||
|
||||
import numpy as np
|
||||
from Qt import QtCore
|
||||
|
||||
from qspectrumanalyzer import subprocess
|
||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||
|
||||
|
||||
@ -71,7 +72,7 @@ class PowerThread(BasePowerThread):
|
||||
cmdline.extend(shlex.split(additional_params))
|
||||
|
||||
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
universal_newlines=True, console=False)
|
||||
|
||||
def parse_output(self, line):
|
||||
"""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
|
||||
from Qt import QtCore
|
||||
|
||||
from qspectrumanalyzer import subprocess
|
||||
from qspectrumanalyzer.backends import BaseInfo, BasePowerThread
|
||||
|
||||
try:
|
||||
@ -12,20 +13,6 @@ except ImportError:
|
||||
print('soapy_power module not found!')
|
||||
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):
|
||||
"""soapy_power device metadata"""
|
||||
@ -47,12 +34,12 @@ class Info(BaseInfo):
|
||||
def help_device(cls, executable, device):
|
||||
try:
|
||||
text = subprocess.check_output([executable, '--detect'], universal_newlines=True,
|
||||
stderr=subprocess.DEVNULL,
|
||||
env=dict(os.environ, COLUMNS='125'))
|
||||
stderr=subprocess.DEVNULL, env=dict(os.environ, COLUMNS='125'),
|
||||
console=False)
|
||||
text += '\n'
|
||||
text += subprocess.check_output([executable, '--device', device, '--info'], universal_newlines=True,
|
||||
stderr=subprocess.DEVNULL,
|
||||
env=dict(os.environ, COLUMNS='125'))
|
||||
stderr=subprocess.DEVNULL, env=dict(os.environ, COLUMNS='125'),
|
||||
console=False)
|
||||
except subprocess.CalledProcessError as e:
|
||||
text = e.output
|
||||
except OSError:
|
||||
@ -101,7 +88,7 @@ class PowerThread(BasePowerThread):
|
||||
os.set_inheritable(self.pipe_write_fd, True)
|
||||
|
||||
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
|
||||
settings = QtCore.QSettings()
|
||||
@ -142,7 +129,7 @@ class PowerThread(BasePowerThread):
|
||||
creationflags = 0
|
||||
|
||||
self.process = subprocess.Popen(cmdline, close_fds=False, universal_newlines=False,
|
||||
creationflags=creationflags)
|
||||
creationflags=creationflags, console=False)
|
||||
|
||||
os.close(self.pipe_write_fd)
|
||||
if sys.platform == 'win32':
|
||||
|
@ -106,8 +106,8 @@ class DataStorage(QtCore.QObject):
|
||||
def update(self, data):
|
||||
"""Update data storage"""
|
||||
if self.y is not None and len(data["y"]) != len(self.y):
|
||||
print("{:d} bins coming from backend, expected {:d}".format(len(data["y"]), len(self.y)))
|
||||
return
|
||||
print("{:d} bins coming from backend, expected {:d}".format(len(data["y"]), len(self.y)))
|
||||
return
|
||||
|
||||
self.average_counter += 1
|
||||
|
||||
|
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