Найти - Пользователи
Полная версия: Создание COM-сервера на Python
Начало » Python для экспертов » Создание COM-сервера на Python
1
Все ники заняты
Хотелось бы получить простейший пример.
В инете нашёл только примеры, подобные такому:
class TestCOM:
    _public_methods_ = ['Version']
    _reg_progid_ = "Python.TestCOM"
    # Use "print pythoncom.CreateGuid()"
    _reg_clsid_ = "{456AEEC9-D56B-4A1C-8670-36BB7B51A805}"
    
    def __init__(self):
        pass
    
    def Version(self):
        return '0.001'
 
if __name__ == '__main__':
    print "Registering COM server..."
    import win32com.server.register
    win32com.server.register.UseCommandLine(TestCOM)
Однако, не работает. Регистрируется этот COM-сервер нормально, но при попытке вызвать его из Visual Basic выдаёт ошибку “'module' object has no attribute ‘TestCOM’, pythoncom error: Unexpected gateway error”.
И как объявить свойства?
bialix
с СОМ опыта практически нет. Но я знаю, что в книге Mark Hammond ‘Python Programming on Win32’ эти вопросы очень подробно освещены. Книга есть в закромах родины и кажется на сайте О'Рэйли выложена вся или частями.
Все ники заняты
Пример в принципе и является цитатой из этой книги. А на сайте О'Рэйли книга выложена далеко не полностью. Так что попробуем подождать здесь кого-нибудь, кто имел дело с COM…
bialix
у славоника вроде лежала книга полностью.
Ferroman
Точно есть у славоника, я скачал оттуда.
Примеры из книги:
# SimpleCOMServer.py - A sample COM server - almost as small as they come!
# 
# We expose a single method in a Python COM object.
class PythonUtilities:
    _public_methods_ = [ 'SplitString' ]
    _reg_progid_ = "PythonDemos.Utilities"
    # NEVER copy the following ID 
    # Use "print pythoncom.CreateGuid()" to make a new one.
    _reg_clsid_ = "{41E24E95-D45A-11D2-852C-204C4F4F5020}"
    
    def SplitString(self, val, item=None):
        import string
        if item != None: item = str(item)
        return string.split(str(val), item)
# Add code so that when this script is run by
# Python.exe, it self-registers.
if __name__=='__main__':
    print "Registering COM server..."
    import win32com.server.register
    win32com.server.register.UseCommandLine(PythonUtilities)

The bulk of the class definition is taken up by the special attributes:

_public_methods_
A list of all methods in the object that are to be exposed via COM; the sample exposes only one method, SplitString.

_reg_progid_
The ProgID for the new object, that is, the name that the users of this object must use to create the object.

_reg_clsid_
The unique CLSID for the object. As noted in the source code, you must never copy these IDs, but create new ones using pythoncom.CreateGuid().

example is how to work with COM interfaces from Python, not what these particular interfaces do:
# DumpStorage.py - Dumps some user defined properties 
# of a COM Structured Storage file.
import pythoncom
from win32com import storagecon # constants related to storage functions.
# These come from ObjIdl.h
FMTID_UserDefinedProperties = "{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"
PIDSI_TITLE               = 0x00000002
PIDSI_SUBJECT             = 0x00000003
PIDSI_AUTHOR              = 0x00000004
PIDSI_CREATE_DTM          = 0x0000000c
def PrintStats(filename):
    if not pythoncom.StgIsStorageFile(filename):
        print "The file is not a storage file!"
        return
    # Open the file.
    flags = storagecon.STGM_READ | storagecon.STGM_SHARE_EXCLUSIVE
    stg = pythoncom.StgOpenStorage(filename, None, flags )
    # Now see if the storage object supports Property Information.
    try:
        pss = stg.QueryInterface(pythoncom.IID_IPropertySetStorage)
    except pythoncom.com_error:
        print "No summary information is available"
        return
    # Open the user defined properties.
    ps = pss.Open(FMTID_UserDefinedProperties)
    props = PIDSI_TITLE, PIDSI_SUBJECT, PIDSI_AUTHOR, PIDSI_CREATE_DTM
    data = ps.ReadMultiple( props )
    # Unpack the result into the items.
    title, subject, author, created = data
    print "Title:", title
    print "Subject:", subject
    print "Author:", author
    print "Created:", created.Format()
if __name__=='__main__':
    import sys
    if len(sys.argv)<2:
        print "Please specify a file name"
    else:
        PrintStats(sys.argv[1])
The first step is to check whether the file is indeed a structured storage file, then call pythoncom.StgOpenStorage() to obtain a Python PyIStorage interface object. You call the Python interface objects just like normal Python objects, as you'd expect. The QueryInterface() method can be used on any Python interface object, and returns a new interface object or throws an exception.

The output of running the example over the Microsoft Word document that contains this chapter is:
C:\Scripts>python.exe DumpStorage.py "Python and COM.doc"
Title: Python and COM
Subject:
Author: Mark Hammond
Created: 03/04/99 00:41:00

C:\Scripts>
A final note on native interfaces: Python can't support arbitrary COM interfaces; the pythoncom module (or a pythoncom extension) must have built-in support for the interface. Fortunately, there are tools pythoncom developers use that largely automate the process of supporting new interfaces.

Надеюсь поможет.
Все ники заняты
Ferroman
К сожалению, этот пример COM-сервера не запускается с той же самой ошибкой, которую я уже привёл в самом первом посте.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB