Hi Giovanni and thanks for a quick response.
I forgot to say that the module files ARE created in that gen_py folder
correctly AFAICS but gencache._GetModule() is not picking it up. It
seems that Dispatch() also calls _GetModule() several times but I have
not yet checked if it fails and Dispatch then gets the module another way.
(Is there any debugger that you can use for pyinstaller created
programs? I'm going mad just putting in prints/MessageBoxs.)
Again if you leave the Python\...\gen_py or %temp%\gen_py on your system
then the moduels get picked up there. That is probably a clue and
perhaps a bug as I really only want it to look in the pyInstaller copy
and this causes possible end user bugs.
I'm not fluent with win32com, I barely used Dispatch() once. Mind explaining
the difference between the two? Basically, I knew of two different ways:
> - Using Dispatch() (fully dynamic)
> - Generate the wrapper with makepy.py, import it with "import Foo",
and use the
> classes it exports directly.
>
OK in COM terms, automation/Dispatch interfaces work in 2 ways.
1 - Late Binding: given a function name you call GetIDsFromNames() to
get the ID and then call Invoke() to call the function. Parameters are
passed in by a reference parameter to a special structure. You have to
do all the parameter block construction and type conversion and so it is
pretty inefficient.
2 - Early Binding: we do as much as we can in an initial phase. You get
all the information about the functions and types from a typelibrary and
create wrapper functions to do the martialing and also skip the
GetIDSFromNames stage.
In terms of Python the wrapper modules give you early binding.
Dispatch() tries to generate them for you if they were not already
created by makepy. If it fails it falls back to late binding (Dynamic).
EnsureDispatch() however insists that the wrapper functions exist, also
creating them if required. There are obviously other differences, one of
which is causing the problem, but it is a lot of code to compare.
I never heard of EnsureDispath.
I almost suspect I am the only person using it :-(. It was at Mark
Hammonds suggestion to fix the failure I was having using COM constants
and sinking COM events (a COM callback).
Does it work if
you add "import win32com.gen_py.C866CA3A-32F7-11D2-9602-00C04F8EE628x0x5x0" in
your test file?
Unfortunately I can't use that for a very good reason. I use PowerPoint
and that uses a different CLSID (that strange modulename above) for each
version. I don't care what version the user has and if I did what you
suggest or used makepy I would only support that single version.
EnsureDispatch and DIspatch() take the progID which is a version
independent identifier.
The rules of COM are that is should fall back to an older version so I
should be able to specify the latest and get any older. PowerPoint has
broken that by using a completely new CLSID not just the version number
at the end (x0x5x0).
BTW I noticed a fix for this on the py2exe wiki that simply sets
gencache.readonly = false casing dispatch to create the fields as
discussed above. But that has no effect here as it is already false, a
much better solution with your local gen_py.
I guess because Dispatch() really doesn't need any external module, but
directly find and inspect the .DLL.
Yes, as discussed above it falls back to late/dynamic binding. I need
the wrappers.
One problem is that I don't have a development XP machine handy, and I don't
know COM enough. Can you construct a different testcase which doesn't strictly
require XP? I guess connecting to any older COM dll is good to reproduce...
Ok what *do* you have access to. I will have to try a simple object or
create a test case. Can you install
http://prdownloads.sourceforge.net/powertalk/SAPITTS3.exe?download
or
http://fullmeasure.co.uk/powertalk/SAPITTS3.exe as SF seems to be slow.
That will install SAPI for you.
It's not that "mysterious" :) You can have a look at
support/rthooks/win32comgenpy.py which is the module that is run before your
code starts. You will see that it creates the local gen_py folder, and
monkey-patch it into win32com.__gen_path__.
Thanks I'll look. I scanned the notes and got rather lossed, so I must
be missing some concepts somewhere.
AAAAHHHH I wonder if the problem is that _GetModule() does not look in
win32com.__gen_path__ and Dispatch() false back to using __genpath__
after calling _GetModule() and EnsureDispatch does not? DOes that seem
possible?
Steve
_______________________________________________
PyInstaller mailing list
[email protected]
http://lists.hpcf.upr.edu/mailman/listinfo/pyinstaller