Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 64 additions & 34 deletions Pythonwin/pywin/framework/intpyapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
import win32ui
import __main__
import sys
import string
import os
from . import app
import traceback
from pywin.mfc import window, afxres, dialog
from pywin.mfc import afxres, dialog
import commctrl
from . import dbgcommands

lastLocateFileName = ".py" # used in the "File/Locate" dialog...

# todo - _SetupSharedMenu should be moved to a framework class.
def _SetupSharedMenu_(self):
sharedMenu = self.GetSharedMenu()
from pywin.framework import toolmenu
toolmenu.SetToolsMenu(sharedMenu)
from pywin.framework import help
help.SetHelpMenuOtherHelp(sharedMenu)
sharedMenu = self.GetSharedMenu()
from pywin.framework import toolmenu
toolmenu.SetToolsMenu(sharedMenu)
from pywin.framework import help
help.SetHelpMenuOtherHelp(sharedMenu)
from pywin.mfc import docview
docview.DocTemplate._SetupSharedMenu_=_SetupSharedMenu_

Expand Down Expand Up @@ -153,16 +153,19 @@ def InitDDE(self):
# If there is an existing instance, pump the arguments to it.
connection = self.MakeExistingDDEConnection()
if connection is not None:
connection.Exec("self.Activate()")
if self.ProcessArgs(sys.argv, connection) is None:
return 1
except:
# It is too early to 'print' an exception - we
# don't have stdout setup yet!
win32ui.DisplayTraceback(sys.exc_info(), " - error in DDE conversation with Pythonwin")
return 1

def InitInstance(self):
# Allow "/nodde" and "/new" to optimize this!
if "/nodde" not in sys.argv and "/new" not in sys.argv:
if ("/nodde" not in sys.argv and "/new" not in sys.argv
and "-nodde" not in sys.argv and "-new" not in sys.argv):
if self.InitDDE():
return 1 # A remote DDE client is doing it for us!
else:
Expand Down Expand Up @@ -200,7 +203,11 @@ def InitInstance(self):
pass

# Finally process the command line arguments.
self.ProcessArgs(sys.argv)
try:
self.ProcessArgs(sys.argv)
except:
# too early for printing anything.
win32ui.DisplayTraceback(sys.exc_info(), " - error processing command line args")

def ExitInstance(self):
win32ui.DestroyDebuggerThread()
Expand All @@ -225,50 +232,76 @@ def Activate(self):
def ProcessArgs(self, args, dde = None):
# If we are going to talk to a remote app via DDE, then
# activate it!
if dde is not None: dde.Exec("self.Activate()")
if len(args) and args[0] in ['/nodde','/new']: del args[0] # already handled.
if len(args)<1 or not args[0]: # argv[0]=='' when started without args, just like Python.exe!
return
try:
if args[0] and args[0][0]!='/':
argStart = 0

i = 0
while i < len(args):
argType = args[i]
i += 1
if argType.startswith('-'):
# Support dash options. Slash options are misinterpreted by python init
# as path and not finding usually 'C:\\' ends up in sys.path[0]
argType = '/' + argType[1:]
if not argType.startswith('/'):
argType = win32ui.GetProfileVal("Python","Default Arg Type","/edit").lower()
else:
argStart = 1
argType = args[0]
if argStart >= len(args):
raise TypeError("The command line requires an additional arg.")
if argType=="/edit":
i -= 1 # arg is /edit's parameter
par = i < len(args) and args[i] or 'MISSING'
if argType in ['/nodde', '/new', '-nodde', '-new']:
# Already handled
pass
elif argType.startswith('/goto:'):
gotoline = int(argType[len('/goto:'):])
if dde:
dde.Exec("from pywin.framework import scriptutils\n"
"ed = scriptutils.GetActiveEditControl()\n"
"if ed: ed.SetSel(ed.LineIndex(%s - 1))" % gotoline)
else:
from . import scriptutils
ed = scriptutils.GetActiveEditControl()
if ed: ed.SetSel(ed.LineIndex(gotoline - 1))
elif argType == "/edit":
# Load up the default application.
i += 1
fname = win32api.GetFullPathName(par)
if not os.path.isfile(fname):
# if we don't catch this, OpenDocumentFile() (actually
# PyCDocument.SetPathName() in
# pywin.scintilla.document.CScintillaDocument.OnOpenDocument)
# segfaults Pythonwin on recent PY3 builds (b228)
win32ui.MessageBox(
"No such file: %s\n\nCommand Line: %s" % (
fname, win32api.GetCommandLine()),
"Open file for edit", win32con.MB_ICONERROR)
continue
if dde:
fname = win32api.GetFullPathName(args[argStart])
dde.Exec("win32ui.GetApp().OpenDocumentFile(%s)" % (repr(fname)))
else:
win32ui.GetApp().OpenDocumentFile(args[argStart])
win32ui.GetApp().OpenDocumentFile(par)
elif argType=="/rundlg":
if dde:
dde.Exec("from pywin.framework import scriptutils;scriptutils.RunScript('%s', '%s', 1)" % (args[argStart], ' '.join(args[argStart+1:])))
dde.Exec("from pywin.framework import scriptutils;scriptutils.RunScript(%r, %r, 1)" % (par, ' '.join(args[i + 1:])))
else:
from . import scriptutils
scriptutils.RunScript(args[argStart], ' '.join(args[argStart+1:]))
scriptutils.RunScript(par, ' '.join(args[i + 1:]))
return
elif argType=="/run":
if dde:
dde.Exec("from pywin.framework import scriptutils;scriptutils.RunScript('%s', '%s', 0)" % (args[argStart], ' '.join(args[argStart+1:])))
dde.Exec("from pywin.framework import scriptutils;scriptutils.RunScript(%r, %r, 0)" % (par, ' '.join(args[i + 1:])))
else:
from . import scriptutils
scriptutils.RunScript(args[argStart], ' '.join(args[argStart+1:]), 0)
scriptutils.RunScript(par, ' '.join(args[i + 1:]), 0)
return
elif argType=="/app":
raise RuntimeError("/app only supported for new instances of Pythonwin.exe")
elif argType=='/dde': # Send arbitary command
if dde is not None:
dde.Exec(args[argStart])
dde.Exec(par)
else:
win32ui.MessageBox("The /dde command can only be used\r\nwhen Pythonwin is already running")
i += 1
else:
raise TypeError("Command line arguments not recognised")
except:
# too early for print anything.
win32ui.DisplayTraceback(sys.exc_info(), " - error processing command line args")
raise ValueError("Command line argument not recognised: %s" % argType)


def LoadSystemModules(self):
Expand Down Expand Up @@ -309,7 +342,6 @@ def OnDDECommand(self, command):
#
def OnViewBrowse( self, id, code ):
" Called when ViewBrowse message is received "
from pywin.mfc import dialog
from pywin.tools import browser
obName = dialog.GetSimpleInput('Object', '__builtins__', 'Browse Python Object')
if obName is None:
Expand Down Expand Up @@ -345,9 +377,7 @@ def OnFileRun( self, id, code ):
scriptutils.RunScript(None, None, showDlg)

def OnFileLocate( self, id, code ):
from pywin.mfc import dialog
from . import scriptutils
import os
global lastLocateFileName # save the new version away for next time...

name = dialog.GetSimpleInput('File name', lastLocateFileName, 'Locate Python File')
Expand Down
15 changes: 14 additions & 1 deletion Pythonwin/pywin/framework/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@
# this runs OK. Errors in imported modules are much better - the messages go somewhere (not any more :-)

import sys
import os
import win32api
import win32ui

if not sys.argv:
# Initialize sys.argv from commandline. When sys.argv is empty list (
# different from [''] meaning "no cmd line arguments" ), then C
# bootstrapping or another method of invocation failed to initialize
# sys.argv and it will be done here. ( This was a workaround for a bug in
# win32ui but is retained for other situations. )
argv = win32api.CommandLineToArgv(win32api.GetCommandLine())
sys.argv = argv[1:]
if os.getcwd() not in sys.path and '.' not in sys.path:
sys.path.insert(0, os.getcwd())

# You may wish to redirect error output somewhere useful if you have startup errors.
# eg, 'import win32traceutil' will do this for you.
# import win32traceutil # Just uncomment this line to see error output!
Expand All @@ -37,7 +50,7 @@
sys.appargvoffset = 0
sys.appargv = sys.argv[:]
# Must check for /app param here.
if len(sys.argv)>=2 and sys.argv[0].lower()=='/app':
if len(sys.argv) >= 2 and sys.argv[0].lower() in ('/app', '-app'):
from . import cmdline
moduleName = cmdline.FixArgFileName(sys.argv[1])
sys.appargvoffset = 2
Expand Down
6 changes: 4 additions & 2 deletions Pythonwin/start_pythonwin.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import win32ui
import pywin.framework.intpyapp
# Pretend this script doesn't exist, or pythonwin tries to edit it
import sys
del sys.argv[0]
import sys, os
sys.argv[:] = sys.argv[1:] or [''] # like PySys_SetArgv(Ex)
if sys.path[0] not in ('.', os.getcwd()):
sys.path.insert(0, os.getcwd())
# And bootstrap the app.
app=win32ui.GetApp()
app.InitInstance()
Expand Down
2 changes: 1 addition & 1 deletion Pythonwin/win32uimodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2614,7 +2614,7 @@ extern "C" PYW_EXPORT BOOL Win32uiApplicationInit(Win32uiHostGlue *pGlue, TCHAR
PySys_SetArgv(__argc - 1, __targv + 1);
#else
PyInit_win32ui();
if (argv == NULL) {
if (argv == NULL || !PyList_Check(argv) || !PyList_Size(argv)) {
int myargc;
LPWSTR *myargv = CommandLineToArgvW(GetCommandLineW(), &myargc);
if (myargv) {
Expand Down
2 changes: 1 addition & 1 deletion pywin32_postinstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def RegisterPythonwin(register=True):
classes_root=get_root_hkey()
## Installer executable doesn't seem to pass anything to postinstall script indicating if it's a debug build,
pythonwin_exe = os.path.join(lib_dir, "Pythonwin", "Pythonwin.exe")
pythonwin_edit_command=pythonwin_exe + ' /edit "%1"'
pythonwin_edit_command=pythonwin_exe + ' -edit "%1"'

keys_vals = [
('Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Pythonwin.exe', '', pythonwin_exe),
Expand Down