From: Clive L. <Clive@Lansink.Co.NZ> - 2009-01-25 04:28:53
|
Hello everyone. I have been trying to get a simple com server going using Py2exe. The following is based on the example in the section on using Py2exe with Win32com. I have called it hello.py. I'm calling it from Perl. I've spent several hours on this and have at least got it half working but I do have some issues I can't resolve. I would appreciate it if someone could give me some advice. 1. In the beginning of the sample, we have: if hasattr(sys, 'importers'): # we are running as py2exe-packed executable pythoncom.frozen = 1 sys.frozen = 1 If I register using the local Python interpreter, by entering the command hello.py, and call the server from Perl, it basically hangs for a while and then times out without connecting. However it does work if I register the .exe with hello --register. If I comment out #sys.frozen = 1 it then works when registered using the local Python interpreter as well. What does frozen mean for both sys and pythoncom, and why is it here? I have left sys.frozen = 1 commented out for now. 2. There is the line: _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER I noticed that I couldn't print to stdout unless this line was commented out. With the line commented out, and with the program registered using the local Python interpreter, the print statements print to stdout which is what I want, but with the line in, I get no printing. Can someone explain please what this line is for? I have left this line commented out so at least my com server can print. 3. I want the com server to print to stdout if for no other reason than for debugging. I find that it does print if I register the server using the local Python interpreter, but if I register using the exe built by Py2exe, none of the print statements work, though the server does respond to my Perl test program. Is there a way to get a com server to print even if it is created using Py2exe? The following is my test code: hello.py: import sys import pythoncom if hasattr(sys, 'importers'): # we are running as py2exe-packed executable pythoncom.frozen = 1 #sys.frozen = 1 class HelloWorld: # Commented out because it prevents printing. # _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER if hasattr(sys, 'importers'): # In the py2exe-packed version, specify the module.class # to use. In the python script version, python is able # to figure it out itself. _reg_class_spec_ = "__main__.HelloWorld" _reg_clsid_ = "{B83DD222-7750-413D-A9AD-01B37021B24B}" _reg_desc_ = "Python Test COM Server" _reg_progid_ = "Python.TestServer" _public_methods_ = ['Hello'] _public_attrs_ = ['softspace', 'noCalls'] _readonly_attrs_ = ['noCalls'] def __init__(self): self.softspace = 1 self.noCalls = 0 print "Initialising." # __init__() def Hello(self, who): self.noCalls = self.noCalls + 1 # insert "softspace" number of spaces print "Call to Hello." return "Hello there" + " " * self.softspace + str(who) if __name__ == '__main__': if hasattr(sys, 'importers'): # running as packed executable. if '--register' in sys.argv[1:] or '--unregister' in sys.argv[1:]: # --register and --unregister work as usual import win32com.server.register win32com.server.register.UseCommandLine(HelloWorld) else: # start the server. from win32com.server import localserver localserver.main() else: import win32com.server.register win32com.server.register.UseCommandLine(HelloWorld) setup.py: # This is the distutils script for creating a Python-based com (exe or dll) # server using win32com. This script should be run like this: # # % python setup.py py2exe # # After you run this (from this directory) you will find two directories here: # "build" and "dist". The .dll or .exe in dist is what you are looking for. ############################################################################## from distutils.core import setup import py2exe import sys class Target: def __init__(self, **kw): self.__dict__.update(kw) # for the version info resources (Properties -- Version) self.version = "0.0.1" self.company_name = "my company" self.copyright = "c 2006, my company" self.name = "my com server name" my_com_server_target = Target( description = "my com server", # use module name for win32com exe/dll server #modules = ["dir.my_com_server"], modules = ["hello"], # specify which type of com server you want (exe and/or dll) create_exe = True, create_dll = False ) setup( name="Python.TestServer", # the following two parameters embed support files within exe/dll file options={"py2exe": {"bundle_files": 1, }}, zipfile=None, version="0.0.1", description="my com server", # author, maintainer, contact go here: author="First Last", author_email="some_name@some_company.com", #packages=["dir"], com_server=[my_com_server_target] ) Perl Test program test.pl: use Win32::OLE; $t = Win32::OLE->new('Python.TestServer'); die "Couldn't connect\n" if (not defined $t); $a = $t->Hello("Clive"); print "Got: $a\n"; Clive Lansink Email: Clive@Lansink.Co.NZ Phone: +64 9 520-4242 Mobile: +64 21 663-999 Fax: +64 21 789-150 |
From: Mark H. <ski...@gm...> - 2009-01-25 04:42:51
|
On 25/01/2009 3:27 PM, Clive Lansink wrote: > 1. In the beginning of the sample, we have: > if hasattr(sys, 'importers'): > # we are running as py2exe-packed executable > pythoncom.frozen = 1 > sys.frozen = 1 > If I register using the local Python interpreter, by entering the command hello.py, and call the server from Perl, it basically hangs for a while and then times out without connecting. However it does work if I register the .exe with hello --register. If I comment out > #sys.frozen = 1 > it then works when registered using the local Python interpreter as well. What does frozen mean for both sys and pythoncom, and why is it here? I have left sys.frozen = 1 commented out for now. You should not set sys.frozen - py2exe will do that for you. pywin32 looks at the value in some cases to see what context it is being executed in - see win32com\server\register.py > > > > 2. There is the line: > _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER > I noticed that I couldn't print to stdout unless this line was commented out. With the line commented out, and with the program registered using the local Python interpreter, the print statements print to stdout which is what I want, but with the line in, I get no printing. Can someone explain please what this line is for? I have left this line commented out so at least my com server can print. That line will force your program to run in its own executable, with no console. See the Microsoft documentation for the clsctx param in CoCreateInstance. > 3. I want the com server to print to stdout if for no other reason than for debugging. I find that it does print if I register the server using the local Python interpreter, but if I register using the exe built by Py2exe, none of the print statements work, though the server does respond to my Perl test program. Is there a way to get a com server to print even if it is created using Py2exe? COM objects run in the context of their caller. Consider something like the win32traceutil module for redirecting the print statements to somewhere other than the console. Cheers, Mark |