On 11/05/2010 12:50 PM, Bill Janssen wrote:
Mark Hammond<skippy.hamm...@gmail.com>  wrote:

That's correct.  Using python.exe as the host will involve having a
.py script which imports the servicemanager module then call
PrepareToHostSingle and instantiate the service class - or something
like that :)

How definitive :-).  I'm already generating a python script for each
service, so this could easily be incorporated, if I knew exactly what it
was I have to do.

1.  Set up the sys.path and os.environ["Path"] properly.

2.  import servicemanager

3.  define my class

4.  call servicemanager.PrepareToHostSingle(my class name)

Seem right?

Sounds about right - but reading pythonservice.cpp is really the definitive source to what needs to be done. Sadly I can't find anything more specific, such as a sample.

Another alternative is to ship a slightly modified pythonxx.dll - it
has a feature where a certain string resource contains the basename of
the registry key used at runtime to load the pythonpath - eg, you will
find the resource has "2.6" for Python 2.6 builds.  Using a resource
editor (or even a script using pywin32) to change this to some custom
value will mean the pythonpath can be loaded from a private key in the
registry, meaning you still get isolation from other installed Python
versions.

I could do that, I guess.  I'd like to be able to script all the
preparations, so if it's a GUI step that would be a Bad Thing.  But a
script using pywin32 would be great.  So, I need to know a couple of
things:

1.  What's the name of this "certain string resource"?

2.  How would one write such a pywin32 script :-)?

I wrote this script to answer question #1:

-----------------------------------------------------------------
import sys, os

import win32api, win32con

handle = win32api.LoadLibrary(sys.argv[1])
for rname in win32api.EnumResourceNames(handle, win32con.RT_STRING):
     rvalue = win32api.LoadResource(handle, win32con.RT_STRING, rname)
     print rname, rvalue
-----------------------------------------------------------------

$ python resource.py python26.dll
63 
^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@2^@....@6^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@
$

So, the "name" is 63, and it's a 38-byte value with a lot of nul
characters in it.  I'm unsure of just how to hack it with UpdateResource
-- do I just center the replacement text and pad with nul characters?
And what's the registry key this works against, anyway?  I'd have to
update that as part of my installer, too.

I think the above loaded a string *table*. The resource ID is 1000, and py2exe has some code to deal with updating this for a file. It does:

        from py2exe.resources.StringTables import StringTable, RT_STRING
        from py2exe_util import add_resource, load_resource
        from py2exe.resources.VersionInfo import RT_VERSION

...
        # OK - do the strings.
        s = StringTable()
        # 1000 is the resource ID Python loads for its winver.
        s.add_string(1000, new_winver)
        for id, data in s.binary():
add_resource(ensure_unicode(dll_name), data, RT_STRING, id, False)

While this could be done with pywin32 and the win32api.UpdateResource function, that would probably require some struct magic - the StringTable object in py2exe hides some of this from you.

HTH,

Mark
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to