Skip to content

PY3 PythonWin.exe doesn't process commandline args - sys.argv empty #1541

@kxrob

Description

@kxrob

PythonWin.exe in PY3 versions seems to not process commandline args. Unlike python(w).exe . sys.argv is empty when coming in from C bootstrap. E.g. Explorer/right-click/Edit_with_PythonWin doesn't pre-open file. Patch with semi-solution on Python side below.

  • Steps to reproduce the problem:

Start Pythonwin.exe through Explorer/right-click-any-py-file/EditWithPythonWin or through commandline with args like PythonWin.exe [/edit] anyfile.py .

=> The target py file is not pre-opened in PythonWin. Also sys.argv is an empty list, though sys.executable is set and win32api.GetCommandLine() returns the correct complete commandline.

A breakpoint in intpyapp.py/ProcessArgs via
import pywin.debugger; pywin.debugger.set_trace()
shows that args / sys.argv are obviously missing already when coming in from C bootstrapping - see stack trace and values below.

  • Version of Python and pywin32
    pywin32-228.win-amd64-py3.7.exe

  • Stack trace and values after breakpoint in intpyapp.py/ProcessArgs:

PythonWin 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32.
Portions Copyright 1994-2018 Mark Hammond - see 'Help/About PythonWin' for further copyright information.
This is init script 'C:\\ext\\pythonrc.py' (PYTHONSTARTUP)
import win32api, win32ui, win32con  #,win32gui
import sys, os, time, string, re, math, glob, operator, types, traceback, ctypes
[Dbg]>>> args, sys.argv
([], [])
[Dbg]>>> sys.executable
'C:\\Python37\\Lib\\site-packages\\Pythonwin\\Pythonwin.exe'
[Dbg]>>> win32api.GetCommandLine()
'"C:\\Python37\\Lib\\site-packages\\Pythonwin\\Pythonwin.exe" /edit "C:\\1\\scratch.py"'
[Dbg]>>> traceback.print_stack()
  File "C:\Python37\Lib\site-packages\Pythonwin\pywin\framework\intpyapp.py", line 203, in InitInstance
    self.ProcessArgs(sys.argv)
  File "C:\Python37\Lib\site-packages\Pythonwin\pywin\framework\intpyapp.py", line 230, in ProcessArgs
    if len(args) and args[0] in ['/nodde','/new']: del args[0] # already handled.
  File "C:\Python37\lib\bdb.py", line 88, in trace_dispatch
    return self.dispatch_line(frame)
  File "C:\Python37\lib\bdb.py", line 112, in dispatch_line
    self.user_line(frame)
...
  • This patch semi-solves the problem, but perhaps sys.argv should be better set up in C code.
--- ./framework/intpyapp.py
+++ ./framework/intpyapp.py
@@ -162,6 +162,16 @@
 				win32ui.DisplayTraceback(sys.exc_info(), " - error in DDE conversation with Pythonwin")
 
 	def InitInstance(self):
+		if not sys.argv:
+			# wenn empty list (!= ['']), then win32ui failed to initialize sys.argv 
+			assert sys.version > '3'
+			from ctypes import wintypes, windll, c_int, POINTER
+			windll.shell32.CommandLineToArgvW.restype = POINTER(wintypes.LPWSTR)
+			windll.shell32.CommandLineToArgvW.argtypes = (wintypes.LPCWSTR, wintypes.LPINT)
+			argc = c_int() 
+			argv = windll.shell32.CommandLineToArgvW(win32api.GetCommandLine(), argc)
+			sys.argv = argv[1:argc.value]
+			
 		# Allow "/nodde" and "/new" to optimize this!
 		if "/nodde" not in sys.argv and "/new" not in sys.argv:
 			if self.InitDDE():

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions