Hi all,
I am working on a Windows Explorer context menu handler; Windows 10,
Python 3.4 (both 64 bit), pywin32 version 219 installed (no virtual
environment).
The handler is working fine when running it as a Python source file.
However, I would like to create an executable containing all the
dependencies, so it can be run on PCs that don't have Python installed.
I can't get this to work. I have tried using py2exe and pyinstaller,
with various setup.py and spec file examples, and nothing seems to work.
I've attached a stripped-down version of my code; when registered, it
adds a context menu entry that, when clicked, pops up a message box
showing the item clicked.
Can anyone help me find a way to convert this to an executable that
still works? Thanks!
Regards,
Gertjan.
#!/usr/bin/env python3.4
import sys, os
from os.path import dirname, join, exists
import pythoncom
from win32com.shell import shell, shellcon
import win32gui
import win32gui_struct
import win32con
import win32process
import win32api
IContextMenu_Methods = ["QueryContextMenu", "InvokeCommand", "GetCommandString"]
IShellExtInit_Methods = ["Initialize"]
class ShellExtension:
name = 'ContextMenuTest'
_reg_progid_ = "Python.ShellExtension.ContextMenuTest"
_reg_desc_ = "Contextmenu test"
_reg_clsid_ = "{1055EB80-4862-11E6-8607-101F7414C0D3}"
_com_interfaces_ = [shell.IID_IShellExtInit, shell.IID_IContextMenu]
_public_methods_ = IContextMenu_Methods + IShellExtInit_Methods
def Initialize(self, folder, dataobj, hkey):
print("Initialize")
self.dataobj = dataobj
self.folder = folder
def QueryContextMenu(self, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags):
print("QueryContextMenu")
flags = win32con.MF_BYPOSITION | win32con.MF_STRING
win32gui.InsertMenu(hMenu, indexMenu, flags, idCmdFirst, "Context menu
test")
return 1
def InvokeCommand(self, ci):
print("InvokeCommand")
mask, hwnd, verb, params, dir, nShow, hotkey, hicon = ci
if dir:
mb_flags = win32con.MB_ICONEXCLAMATION | win32con.MB_OK
win32gui.MessageBox(hwnd, dir, "Item clicked", 0)
return
def GetCommandString(self, cmd, typ):
print("GetCommandString:", (cmd, typ))
return ""
def __del__(self):
# Automatically unload the module if and only if a file __debug__ is
# present in the same directory as this file.
path = dirname(__file__)
flagfile = join(path, '__debug__')
if not exists(flagfile):
return
# Flag file exists: unload module
if self.__module__ in sys.modules:
print("Deleting", self.__module__, "module.")
del sys.modules[self.__module__]
# ========== ========== ========== ========== ==========
# Paths in HKCR to register / unregister
REGPATHS = (
r"*\shellex\ContextMenuHandlers\%s",
)
def DllRegisterServer():
import winreg
classid = ShellExtension._reg_clsid_
for path in REGPATHS:
path = path % ShellExtension.name
key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, path)
winreg.SetValueEx(key, None, 0, winreg.REG_SZ, classid)
print(ShellExtension._reg_desc_, "registration complete.")
def DllUnregisterServer():
for path in REGPATHS:
path = path % ShellExtension.name
del_key(path)
print(ShellExtension._reg_desc_, "unregistration complete.")
def del_key(path):
import winreg
try:
key = winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, path)
except WindowsError as details:
import errno
if details.errno != errno.ENOENT:
raise
# ========== ========== ========== ========== ==========
if __name__ == '__main__':
# Loaded as program: register as shell extension
# Register:
# py -3.4 ctxm.py --register
# Unregister:
# py -3.4 ctxm.py --unregister
# No implicit registration
if len(sys.argv) < 2:
print("Use --register or --unregister.")
sys.exit(1)
#
if sys.argv[1] == "/Automate":
from win32com.server import localserver
localserver.serve([ShellExtension._reg_clsid_])
sys.exit(0)
from win32com.server import register
register.UseCommandLine(
ShellExtension,
finalize_register = DllRegisterServer,
finalize_unregister = DllUnregisterServer)
else:
# Loaded as module: use win32traceutil for debugging
# To view output, use:
# py -3.4 -mwin32traceutil
import win32traceutil
print("\n=====\nLoading ctmx module.")
_______________________________________________
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32