Skip to content

Commit

Permalink
[core] Warn user when not launching through shell on Windows (#9250)
Browse files Browse the repository at this point in the history
Authored by: seproDev, Grub4K

Co-authored-by: Simon Sawicki <contact@grub4k.xyz>
  • Loading branch information
seproDev and Grub4K committed Feb 24, 2024
1 parent 998dffb commit 6a6cdcd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
25 changes: 23 additions & 2 deletions yt_dlp/__init__.py
Expand Up @@ -14,7 +14,7 @@
import re
import traceback

from .compat import compat_shlex_quote
from .compat import compat_os_name, compat_shlex_quote
from .cookies import SUPPORTED_BROWSERS, SUPPORTED_KEYRINGS
from .downloader.external import get_external_downloader
from .extractor import list_extractor_classes
Expand Down Expand Up @@ -984,7 +984,28 @@ def _real_main(argv=None):
if pre_process:
return ydl._download_retcode

ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv)
args = sys.argv[1:] if argv is None else argv
ydl.warn_if_short_id(args)

# Show a useful error message and wait for keypress if not launched from shell on Windows
if not args and compat_os_name == 'nt' and getattr(sys, 'frozen', False):
import ctypes.wintypes
import msvcrt

kernel32 = ctypes.WinDLL('Kernel32')

buffer = (1 * ctypes.wintypes.DWORD)()
attached_processes = kernel32.GetConsoleProcessList(buffer, 1)
# If we only have a single process attached, then the executable was double clicked
# When using `pyinstaller` with `--onefile`, two processes get attached
is_onefile = hasattr(sys, '_MEIPASS') and os.path.basename(sys._MEIPASS).startswith('_MEI')
if attached_processes == 1 or is_onefile and attached_processes == 2:
print(parser._generate_error_message(
'Do not double-click the executable, instead call it from a command line.\n'
'Please read the README for further information on how to use yt-dlp: '
'https://github.com/yt-dlp/yt-dlp#readme'))
msvcrt.getch()
_exit(2)
parser.error(
'You must provide at least one URL.\n'
'Type yt-dlp --help to see a list of all options.')
Expand Down
7 changes: 5 additions & 2 deletions yt_dlp/options.py
Expand Up @@ -196,9 +196,12 @@ def parse_known_args(self, args=None, values=None, strict=True):
raise
return self.check_values(self.values, self.largs)

def error(self, msg):
def _generate_error_message(self, msg):
msg = f'{self.get_prog_name()}: error: {str(msg).strip()}\n'
raise optparse.OptParseError(f'{self.get_usage()}\n{msg}' if self.usage else msg)
return f'{self.get_usage()}\n{msg}' if self.usage else msg

def error(self, msg):
raise optparse.OptParseError(self._generate_error_message(msg))

def _get_args(self, args):
return sys.argv[1:] if args is None else list(args)
Expand Down

0 comments on commit 6a6cdcd

Please sign in to comment.