[python-win32] Context menu handler as executable

2016-07-26 Thread Gertjan Klein

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


Re: [python-win32] Context menu handler as executable

2016-07-26 Thread Tim Roberts
Gertjan Klein wrote:
> 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.

Are you testing this on a 64-bit system?  Remember that your 64-bit
process will only work on 64-bit systems.

What actually happens when you try to run it?

-- 
Tim Roberts, t...@probo.com
Providenza & Boekelheide, Inc.

___
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Context menu handler as executable

2016-07-26 Thread Gertjan Klein

Tim Roberts wrote:

Gertjan Klein wrote:

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.


Are you testing this on a 64-bit system?  Remember that your 64-bit
process will only work on 64-bit systems.


Yes, Windows and Python are both 64 bit. Note that the handler works 
fine as a python file, just not as an executable.



What actually happens when you try to run it?


I guess I should have been more specific there... ;-)  I have py2exe or 
pyinstaller create an executable; this registers itself without any 
error messages, and registry entries do appear in the registry. However, 
no context menu item appears, and nothing I tried showed any evidence of 
my code being run.


I don't know nearly enough of Windows programming to have even an idea 
of what could be wrong, or debug further.


Regards,
Gertjan.



___
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32