Windows: Fix a regression in the previous release that caused terminal windows to popup momentarily when adding PDF files or converting them. Fixes #2115246 [When converting / importing PDF file into 8.5 on windows (10/11), multiple command windows will pop up for fraction of a second](https://bugs.launchpad.net/calibre/+bug/2115246)

This commit is contained in:
Kovid Goyal 2025-06-24 17:29:51 +05:30
parent cb1d032ef7
commit 42fb76fef7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 19 additions and 12 deletions

View File

@ -25,6 +25,16 @@ def get_tools():
return pdfinfo, pdftoppm return pdfinfo, pdftoppm
def check_output(*a):
from calibre.ebooks.pdf.pdftohtml import creationflags
return subprocess.check_output(list(a), creationflags=creationflags)
def check_call(*a):
from calibre.ebooks.pdf.pdftohtml import creationflags
subprocess.check_call(list(a), creationflags=creationflags)
def read_info(outputdir, get_cover): def read_info(outputdir, get_cover):
''' Read info dict and cover from a pdf file named src.pdf in outputdir. ''' Read info dict and cover from a pdf file named src.pdf in outputdir.
Note that this function changes the cwd to outputdir and is therefore not Note that this function changes the cwd to outputdir and is therefore not
@ -37,7 +47,7 @@ def read_info(outputdir, get_cover):
ans = {} ans = {}
try: try:
raw = subprocess.check_output([pdfinfo, '-enc', 'UTF-8', '-isodates', 'src.pdf']) raw = check_output(pdfinfo, '-enc', 'UTF-8', '-isodates', 'src.pdf')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
prints(f'pdfinfo errored out with return code: {e.returncode}') prints(f'pdfinfo errored out with return code: {e.returncode}')
return None return None
@ -61,7 +71,7 @@ def read_info(outputdir, get_cover):
# https://cgit.freedesktop.org/poppler/poppler/commit/?id=c91483aceb1b640771f572cb3df9ad707e5cad0d # https://cgit.freedesktop.org/poppler/poppler/commit/?id=c91483aceb1b640771f572cb3df9ad707e5cad0d
# we can no longer rely on it. # we can no longer rely on it.
try: try:
raw = subprocess.check_output([pdfinfo, '-meta', 'src.pdf']).strip() raw = check_output(pdfinfo, '-meta', 'src.pdf').strip()
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
prints(f'pdfinfo failed to read XML metadata with return code: {e.returncode}') prints(f'pdfinfo failed to read XML metadata with return code: {e.returncode}')
else: else:
@ -74,8 +84,8 @@ def read_info(outputdir, get_cover):
if get_cover: if get_cover:
try: try:
subprocess.check_call([pdftoppm, '-singlefile', '-jpeg', '-cropbox', check_call(pdftoppm, '-singlefile', '-jpeg', '-cropbox',
'src.pdf', 'cover']) 'src.pdf', 'cover')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
prints(f'pdftoppm errored out with return code: {e.returncode}') prints(f'pdftoppm errored out with return code: {e.returncode}')
@ -85,21 +95,17 @@ def read_info(outputdir, get_cover):
def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', prefix='page-images'): def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', prefix='page-images'):
pdftoppm = get_tools()[1] pdftoppm = get_tools()[1]
outputdir = os.path.abspath(outputdir) outputdir = os.path.abspath(outputdir)
args = {}
if iswindows:
args['creationflags'] = subprocess.HIGH_PRIORITY_CLASS | subprocess.CREATE_NO_WINDOW
try: try:
subprocess.check_call([ check_call(
pdftoppm, '-cropbox', '-' + image_format, '-f', str(first), pdftoppm, '-cropbox', '-' + image_format, '-f', str(first),
'-l', str(last), pdfpath, os.path.join(outputdir, prefix) '-l', str(last), pdfpath, os.path.join(outputdir, prefix))
], **args)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise ValueError(f'Failed to render PDF, pdftoppm errorcode: {e.returncode}') raise ValueError(f'Failed to render PDF, pdftoppm errorcode: {e.returncode}')
def is_pdf_encrypted(path_to_pdf): def is_pdf_encrypted(path_to_pdf):
pdfinfo = get_tools()[0] pdfinfo = get_tools()[0]
raw = subprocess.check_output([pdfinfo, path_to_pdf]) raw = check_output(pdfinfo, path_to_pdf)
q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE) q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE)
if q is not None: if q is not None:
return q.group(1) == b'yes' return q.group(1) == b'yes'

View File

@ -16,11 +16,12 @@ from calibre.utils.cleantext import clean_xml_chars
from calibre.utils.ipc import eintr_retry_call from calibre.utils.ipc import eintr_retry_call
PDFTOHTML = 'pdftohtml' + ('.exe' if iswindows else '') PDFTOHTML = 'pdftohtml' + ('.exe' if iswindows else '')
creationflags = subprocess.DETACHED_PROCESS if iswindows else 0
def popen(cmd, **kw): def popen(cmd, **kw):
if iswindows: if iswindows:
kw['creationflags'] = subprocess.DETACHED_PROCESS kw['creationflags'] = creationflags
return subprocess.Popen(cmd, **kw) return subprocess.Popen(cmd, **kw)