Uploaded Test files

This commit is contained in:
Batuhan Berk Başoğlu 2020-11-12 11:05:57 -05:00
parent f584ad9d97
commit 2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions

View file

@ -0,0 +1,104 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>Generated Python COM Support</TITLE>
<META NAME="Version" CONTENT="8.0.3410">
<META NAME="Date" CONTENT="10/11/96">
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY TEXT="#000000" LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">
<P><IMG SRC="image/pycom_blowing.gif" WIDTH=549 HEIGHT=99 ALT="Python and COM - Blowing the others away"></P>
<H1>Generated Python COM Support</H1>
<P>This file describes how the Python COM extensions support "generated files". The information contained here is for expert Python users, and people who need to take advantage of the advanced features of the support. More general information is available in the <A HREF="QuickStartClientCom.html">Quick Start to Client Side COM</A> documentation.</P>
<H2>Introduction</H2>
<P>Generated Python COM support means that a .py file exists behind a particular COM object. This .py file is created by a generation process from a COM type library.</P>
<P>This documentation talks about the process of the creation of the .py files.</P>
<H2>Design Goals</H2>
<P>The main design goal is that the Python programmer need not know much about the type library they wish to work with. They need not know the name of a specific Python module to use a type library. COM uses an IID, version and LCID to identify a type library. Therefore, the Python programmer only need know this information to obtain a Python module.</P>
<H2>How to generate support files</H2>
<P>Support files can be generated either "off-line" by the makepy utility, or in custom Python code.</P>
<P>Using makepy is in many ways far simpler - you simply pick the type library and you are ready to go! The <A HREF="QuickStartClientCom.html">Quick Start to Client Side COM</A> documentation describes this process.</P>
<P>Often however, you will want to use code to ensure the type library has been processed. This document describes that process.</P>
<H2>Usage</H2>
<P>The win32com.client.gencache module implements all functionality. As described above, if you wish to generate support from code, you need to know the IID, version and LCID of the type library.</P>
<P>The following functions are defined. The best examples of their usage is probably in the Pythonwin OCX Demos, and the COM Test Suite (particularly testMSOffice.py)</P>
<P>Note that the gencache.py file supports being run from the command line, and provides some utilities for managing the cache. Run the file to see usage options.</P>
<H2>Using makepy to help with the runtime generation</H2>
<P>makepy supports a "-i" option, to print information about a type library. When you select a type library, makepy will print out 2 lines of code that you cant paste into your application. This will then allow your module to generate the makepy .py file at runtime, but will only take you a few seconds!</P>
<H2>win32com.client.gencache functions</H2>
<H3>def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None):</H3>
<P>Generate support for a type library.</P>
<P>Given the IID, LCID and version information for a type library, generate and import the necessary support files.</P>
<B><P>Returns</P>
</B><P>The Python module. No exceptions are caught.</P>
<B><P>Params</P>
</B><I><P>typelibCLSID</I><BR>
IID of the type library.</P>
<I><P>major</I><BR>
Integer major version.</P>
<I><P>minor</I><BR>
Integer minor version.</P>
<I><P>lcid</I><BR>
Integer LCID for the library.</P>
<I><P>progressInstance</I><BR>
A class instance to use as the progress indicator, or None to use the default GUI one.&nbsp;</P>
<H3>def EnsureModule(typelibCLSID, lcid, major, minor, progressInstance = None):</H3>
<P>Ensure Python support is loaded for a type library, generating if necessary.</P>
<P>Given the IID, LCID and version information for a type library, check and if necessary generate, then import the necessary support files.</P>
<P>Returns:</P>
<P>The Python module. No exceptions are caught during the generate process.</P>
<B><P>Params</P>
</B><I><P>typelibCLSID</I><BR>
IID of the type library.</P>
<I><P>major</I><BR>
Integer major version.</P>
<I><P>minor</I><BR>
Integer minor version.</P>
<I><P>lcid</I><BR>
Integer LCID for the library.</P>
<I><P>progressInstance</I><BR>
A class instance to use as the progress indicator, or None to use the default GUI one.&nbsp;</P>
<P>&nbsp;</P>
<H3>def GetClassForProgID(<I>progid</I>):</H3>
<P>Get a Python class for a Program ID</P>
<P>Given a Program ID, return a Python class which wraps the COM object</P>
<B><P>Returns</P>
</B><P>The Python class, or None if no module is available.</P>
<B><P>Params</P>
</B><I><P>progid<BR>
</I>A COM ProgramID or IID (eg, "Word.Application")</P>
<P>&nbsp;</P>
<H3>def GetModuleForProgID(progid):</H3>
<P>Get a Python module for a Program ID</P>
<P>Given a Program ID, return a Python module which contains the class which wraps the COM object.</P>
<B><P>Returns</P>
</B><P>The Python module, or None if no module is available.</P>
<B><P>Params:</P>
</B><I><P>progid <BR>
</I>A COM ProgramID or IID (eg, "Word.Application")</P>
<P>&nbsp;</P>
<H3>def GetModuleForCLSID(clsid):</H3>
<P>Get a Python module for a CLSID</P>
<P>Given a CLSID, return a Python module which contains the class which wraps the COM object.</P>
<B><P>Returns</P>
</B><P>The Python module, or None if no module is available.</P>
<B><P>Params</P>
</B><I><P>progid<BR>
</I>A COM CLSID (ie, not the description)</P>
<P>&nbsp;</P>
<H3>def GetModuleForTypelib(typelibCLSID, lcid, major, minor):</H3>
<P>Get a Python module for a type library ID</P>
<B><P>Returns</P>
</B><P>An imported Python module, else None</P>
<B><P>Params</B>:</P>
<I><P>typelibCLSID</I><BR>
IID of the type library.</P>
<I><P>major</I><BR>
Integer major version.</P>
<I><P>minor</I><BR>
Integer minor version</P>
<I><P>lcid</I><BR>
Integer LCID for the library.</P></BODY>
</HTML>

View file

@ -0,0 +1,90 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>Untitled</TITLE>
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY LINK="#0000ff" VLINK="#800080">
<H1><IMG SRC="image/pycom_blowing.gif" WIDTH=549 HEIGHT=99 ALT="Python and COM - Blowing the others away"></H1>
<H1>Python and COM - Implementation Details </H1>
<H2>Introduction </H2>
<P>This document describes the technical implementation of the COM support in Python. It is primarily concerned with the underlying C++ interface to COM, although general Python issues are touched. </P>
<P>This document is targeted at people who wish to maintain/enhance the standard COM support (typically by writing extension modules). For information on using Python and COM from a Python programmers perspective, please see the <A HREF="docindex.html">documentation index</A>. </P>
<H2>General COM Support. </H2>
<P>COM support in Python can be broken into 2 general areas - C++ support, and Python support. C++ support exists in the core PythonCOM module (plus any PythonCOM extension modules). Python support exists in the .py files that accompany the core module. </P>
<H2>Naming Conventions </H2>
<P>The naming conventions used by Python code will be: </P>
<UL>
<LI>The Python "New Import" (ni) module will be used, allowing packages, or nested modules. </LI>
<LI>The package name will be "win32com". </LI>
<LI>The core module name will be "pythoncom" (ie, "win32com.pythoncom") </LI></UL>
<P>The rest of the naming conventions are yet to be worked out. </P>
<H2>Core COM support. </H2>
<P>This section is involved with the core C++ support in "pythoncom". </P>
<P>The organisation of PythonCOM support falls into 3 discrete areas. </P>
<H3>COM Client Support </H3>
<P>This is the ability to manipulate other COM objects via their exposed interface. This includes use of IDispatch (eg using Python to start Microsoft Word, open a file, and print it.) but also all client side IUnknown derived objects fall into this category, including ITypeLib and IConnectionPoint support. </P>
<H3>COM Server Support </H3>
<P>This is ability for Python to create COM Servers, which can be manipulated by another COM client. This includes server side IDispatch (eg, Visual Basic starting a Python interpreter, and asking it to evaluate some code) but also all supported server side IUnknown derived classes. </P>
<H3>Python/COM type and value conversion </H3>
<P>This is internal code used by the above areas to managed the conversion to and from Python/COM types and values. This includes code to convert an arbitrary Python object into a COM variant, manages return types, and a few other helpers. </P>
<H2>COM Structures and Python Types </H2>
<P>OLE supports many C level structures for the COM API, which must be mapped to Python. </P>
<H3>VARIANT </H3>
<P>Variants are never exposed as such to Python programs. The internal framework always converts all variants to and from Python types. In some cases, type descriptions may be used, which force specific mappings, although in general the automatic conversion works fine. </P>
<H3>TYPEDESC </H3>
<P>A tuple, containing the elements of the C union. This union will be correctly decoded by the support code. </P>
<H3>ELEMDESC </H3>
<P>A tuple of TYPEDESC and PARAMDESC objects. </P>
<H3>FUNCDESC </H3>
<P>A funcdesc is a large and unwieldy tuple. Documentation to be supplied. </P>
<H3>IID/CLSID </H3>
<P>A native IID in Python is a special type, defined in pythoncom. Whenever a CLSID/IID is required, typically either an object, a tuple of type "iii(iiiiiiii)" or string can be used. </P>
<P>Helper functions are available to convert to and from IID/CLSID and strings. </P>
<H2>COM Framework </H2>
<P>Both client and server side support have a specific framework in place to assist in supporting the widest possible set of interfaces. The framework allows external extension DLLs to be written, which extend the interfaces available to the Python user. </P>
<P>This allows the core PythonCOM module to support a wide set of common interfaces, and other extensions to support anything obscure. </P>
<H3>Client Framework </H3>
<H4>QueryInterface and Types </H4>
<P>When the only support required by Python is IDispatch, everything is simple - every object returned from QueryInterface is a PyIDispatch object. But this does not extend to other types, such as ITypeLib, IConnectionPoint etc., which are required for full COM support. </P>
<P>For example, consider the following C++ psuedo-code: </P>
<CODE><P>IConnectionPoint *conPt;<BR>
someIDispatch-&gt;QueryInterface(IID_IConnectionPoint, (void **)&amp;conPt);<BR>
// Note the IID_ and type of the * could be anything!</CODE> </P>
<P>This cast, and knowledge of a specific IID_* to type must be simulated in Python. </P>
<P>Python/COM will therefore maintain a map of UID's to Python type objects. Whenever QueryInterface is called, Python will lookup this map, to determine if the object type is supported. If the object is supported, then an object of that type will be returned. If the object is not supported, then a PyIUnknown object will be returned. </P>
<P>Note that PyIDispatch will be supported by the core engine. Therefore: </P>
<CODE><P>&gt;&gt;&gt; disp=someobj.QueryInterface(win32com.IID_Dispatch) </P>
</CODE><P>will return a PyIDispatch object, whereas </P>
<CODE><P>&gt;&gt;&gt; unk=someobj.QueryInterface(SomeUnknownIID) # returns PyIUnknown<BR>
&gt;&gt;&gt; disp=unk.QueryInterface(win32com.IID_Dispatch) <BR>
&gt;&gt;&gt; unk.Release() # Clean up now, rather than waiting for unk death.</CODE> </P>
<P>Is needed to convert to an IDispatch object. </P>
<H4>Core Support </H4>
<P>The core COM support module will support the IUnknown, IDispatch, ITypeInfo, ITypeLib and IConnectionPointContainer and IConnectionPoint interfaces. This implies the core COM module supports 6 different OLE client object types, mapped to the 6 IID_*'s representing the objects. (The IConnection* objects allow for Python to repsond to COM events) </P>
<P>A psuedo-inheritance scheme is used. The Python types are all derived from the Python IUnknown type (PyIUnknown). Therefore all IUnknown methods are automatically available to all types, just as it should be. The PyIUnknown type manages all object reference counts and destruction. </P>
<H4>Extensibility </H4>
<P>To provide the above functionality, a Python map is provided, which maps from a GUID to a Python type object. </P>
<P>The advantage of this scheme is an external extension modules can hook into the core support. For example, imagine the following code: </P>
<CODE><P>&gt;&gt;&gt; import myextracom # external .pyd supporting some interface.<BR>
# myextracom.pyd will do the equivilent of</CODE> </P>
<CODE><P># pythoncom.mapSupportedTypes(myextracom.IID_Extra, myextracom.ExtraType) <BR>
&gt;&gt;&gt; someobj.QueryInterface(myextracom.IID_Extra)</CODE> </P>
<P>Would correctly return an object defined in the extension module. </P>
<H3>Server Framework </H3>
<H4>General Framework </H4>
<P>A server framework has been put in place which provides the following features: </P>
<P>All Interfaces provide VTBL support - this means that the Servers exposed by Python are callable from C++ and other compiled languages. </P>
<P>Supports full "inproc" servers. This means that no external .EXE is needed making Python COM servers available in almost all cases. </P>
<P>An extensible model which allows for extension modules to provide server support for interfaces defined in that module. A map is provided which maps from a GUID to a function pointer which creates the interface. </P>
<H3>Python and Variant Types Conversion </H3>
<P>In general, Python and COM are both "type-less". COM is type-less via the VARIANT object, which supports many types, and Python is type-less due to its object model. </P>
<P>There are a number of areas where Python and OLE clash. </P>
<H4>Parameters and conversions. </H4>
<P>For simple calls, there are 2 helpers available which will convert to and from PyObjects and VARIANTS. The call to convert a Python object to a VARIANT is simple in that it returns a VARIANT of the most appropriate type for the Python object - ie, the type of the Python object determines the resulting VARIANT type. </P>
<P>There are also more complex conversion routines available, wrapped in a C++ helper class. Typically, these helpers are used whenever a specific variant type is known (eg, when an ITypeInfo is available for the object being used). In this case, all efforts are made to convert the Python type to the requested variant type - ie, in this situation, the VARIANT type determines how the Python object is coerced. In addition, this code supports the use of "ByRef" and pointer paramaters, providing and freeing any buffers necessary for the call. </P></BODY>
</HTML>

View file

@ -0,0 +1,82 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>Quick Start to Client side COM and Python</TITLE>
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY LINK="#0000ff" VLINK="#800080">
<H1>Quick Start to Client side COM and Python</H1>
<H2>Introduction</H2>
<P>This documents how to quickly start using COM from Python. It is not a thorough discussion of the COM system, or of the concepts introduced by COM.</P>
<P>Other good information on COM can be found in various conference tutorials - please see <A HREF="http://starship.python.net/crew/mhammond/conferences">the collection of Mark's conference tutorials</A></P>
<P>For information on implementing COM objects using Python, please see <A HREF="http://www.python.org/windows/win32com/QuickStartServerCom.html">a Quick Start to Server side COM and Python</A></P>
<P>In this document we discuss the following topics:</P>
<UL>
<LI><A HREF="#Using">Using a COM object from Python</A> </LI>
<LI><A HREF="#WhatObjects">How do I know which objects are available?</A> </LI>
<LI><A HREF="#StaticDispatch">Static Dispatch/Type Safe objects (using the new improved makepy.py)</A></LI>
<LI><A HREF="#UsingComConstants">Using COM Constants with makepy.</A></LI></UL>
<H2>Quick Start</H2>
<H3><A NAME="Using">To use a COM object from Python</A></H3>
<CODE><P>import win32com.client<BR>
o = win32com.client.Dispatch("Object.Name")<BR>
o.Method()<BR>
o.property = "New Value"<BR>
print o.property</P>
</CODE><P>Example</P>
<CODE><P>o = win32com.client.Dispatch("Excel.Application")<BR>
o.Visible = 1<BR>
o.Workbooks.Add() # for office 97 95 a bit different!<BR>
o.Cells(1,1).Value = "Hello"</CODE> </P>
<P>And we will see the word "Hello" appear in the top cell. </P>
<H3><A NAME="WhatObjects">How do I know which methods and properties are available?</A></H3>
<P>Good question. This is hard! You need to use the documentation with the products, or possibly a COM browser. Note however that COM browsers typically rely on these objects registering themselves in certain ways, and many objects to not do this. You are just expected to know.</P>
<H4>The Python COM browser</H4>
<P>PythonCOM comes with a basic COM browser that may show you the information you need. Note that this package requires Pythonwin (ie, the MFC GUI environment) to be installed for this to work.</P>
<P>There are far better COM browsers available - I tend to use the one that comes with MSVC, or this one!</P>
<P>To run the browser, simply select it from the Pythonwin <I>Tools</I> menu, or double-click on the file <I>win32com\client\combrowse.py</I></P>
<H2><A NAME="StaticDispatch">Static Dispatch (or Type Safe) objects</A></H2>
<P>In the above examples, if we printed the '<CODE>repr(o)</CODE>' object above, it would have resulted in</P>
<CODE><P>&lt;COMObject Excel.Application&gt;</P>
</CODE><P>This reflects that the object is a generic COM object that Python has no special knowledge of (other than the name you used to create it!). This is known as a "dynamic dispatch" object, as all knowledge is built dynamically. The win32com package also has the concept of <I>static dispatch</I> objects, which gives Python up-front knowledge about the objects that it is working with (including arguments, argument types, etc)</P>
<P>In a nutshell, Static Dispatch involves the generation of a .py file that contains support for the specific object. For more overview information, please see the documentation references above.</P>
<P>The generation and management of the .py files is somewhat automatic, and involves one of 2 steps:</P>
<UL>
<LI>Using <I>makepy.py</I> to select a COM library. This process is very similar to Visual Basic, where you select from a list of all objects installed on your system, and once selected the objects are magically useable. </LI></UL>
<P>or</P>
<UL>
<LI>Use explicit code to check for, and possibly generate, support at run-time. This is very powerful, as it allows the developer to avoid ensuring the user has selected the appropriate type library. This option is extremely powerful for OCX users, as it allows Python code to sub-class an OCX control, but the actual sub-class can be generated at run-time. Use <I>makepy.py</I> with a </I>-i</I> option to see how to include this support in your Python code.</LI></UL>
<P>The <I>win32com.client.gencache</I> module manages these generated files. This module has <A HREF="GeneratedSupport.html">some documentation of its own</A>, but you probably don't need to know the gory details!</P>
<H3>How do I get at the generated module?</H3>
<P>You will notice that the generated file name is long and cryptic - obviously not designed for humans to work with! So how do you get at the module object for the generated code?</P>
<P>Hopefully, the answer is <I>you shouldn't need to</I>. All generated file support is generally available directly via <I>win32com.client.Dispatch</I> and <I>win32com.client.constants</I>. But should you ever really need the Python module object, the win32com.client.gencache module has functions specifically for this. The functions GetModuleForCLSID and GetModuleForProgID both return Python module objects that you can use in your code. See the docstrings in the gencache code for more details.</P>
<H3>To generate Python Sources supporting a COM object</H3>
<H4>Example using Microsoft Office 97.</H4>
<P>Either:</P>
<UL>
<LI>Run '<CODE>win32com\client\makepy.py</CODE>' (eg, run it from the command window, or double-click on it) and a list will be presented. Select the Type Library '<CODE>Microsoft Word 8.0 Object Library</CODE>' </LI>
<LI>From a command prompt, run the command '<CODE>makepy.py "Microsoft Word 8.0 Object Library"</CODE>' (include the double quotes). This simply avoids the selection process. </LI>
<LI>If you desire, you can also use explicit code to generate it just before you need to use it at runtime. Run <CODE>'makepy.py -i "Microsoft Word 8.0 Object Library"</CODE>' (include the double quotes) to see how to do this.</LI></UL>
<P>And that is it! Nothing more needed. No special import statements needed! Now, you simply need say</P>
<CODE><P>&gt;&gt;&gt; import win32com.client</P>
<P>&gt;&gt;&gt; w=win32com.client.Dispatch("Word.Application")</P>
<P>&gt;&gt;&gt; w.Visible=1</P>
<P>&gt;&gt;&gt; w</P>
<P>&lt;win32com.gen_py.Microsoft Word 8.0 Object Library._Application&gt;</P>
</CODE><P>Note that now Python knows the explicit type of the object.</P>
<H3><A NAME="UsingComConstants">Using COM Constants</A></H3>
<P>Makepy automatically installs all generated constants from a type library in an object called <I>win32com.clients.constants</I>. You do not need to do anything special to make these constants work, other than create the object itself (ie, in the example above, the constants relating to <I>Word</I> would automatically be available after the <CODE>w=win32com.client.Dispatch("Word.Application</CODE>") statement<CODE>.</P>
</CODE><P>For example, immediately after executing the code above, you could execute the following:</P>
<CODE><P>&gt;&gt;&gt; w.WindowState = win32com.client.constants.wdWindowStateMinimize</P>
</CODE><P>and Word will Minimize.</P></BODY>
</HTML>

View file

@ -0,0 +1,195 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>Quick Start to Server Side COM and Python</TITLE>
<META NAME="Version" CONTENT="8.0.3410">
<META NAME="Date" CONTENT="10/11/96">
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY TEXT="#000000" LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">
<H1>Quick Start to Server side COM and Python</H1>
<H2>Introduction</H2>
<P>This documents how to quickly start implementing COM objects in Python. It is not a thorough discussion of the COM system, or of the concepts introduced by COM.</P>
<P>For more details information on Python and COM, please see the <A HREF="http://www.python.org/windows/win32com/COMTutorial/index.htm">COM Tutorial given by Greg Stein and Mark Hammond at SPAM 6 (HTML format)</A> or download the same tutorial <A HREF="http://www.python.org/windows/win32com/COMTutorial.ppt">in PowerPoint format.</A></P>
<P>For information on using external COM objects from Python, please see <A HREF="QuickStartClientCom.html">a Quick Start to Client side COM and Python</A>.</P>
<P>In this document we discuss the <A HREF="#core">core functionality</A>, <A HREF="#Registering">registering the server</A>, <A HREF="#testing">testing the class</A>, <A HREF="#debugging">debugging the class</A>, <A HREF="#Exception">exception handling</A> and <A HREF="#Policies">server policies</A> (phew!)</P>
<H2><A NAME="core">Implement the core functionality</A></H2>
<H3><A NAME="Using">Implement a stand-alone Python class with your functionality</A></H3>
<CODE><P>class HelloWorld:</P><DIR>
<DIR>
<P>def __init__(self):</P><DIR>
<DIR>
<P>self.softspace = 1</P>
<P>self.noCalls = 0</P></DIR>
</DIR>
<P>def Hello(self, who):</P><DIR>
<DIR>
<P>self.noCalls = self.noCalls + 1</P>
<P># insert "softspace" number of spaces</P>
<P>return "Hello" + " " * self.softspace + who</P></DIR>
</DIR>
</DIR>
</DIR>
</CODE><P>This is obviously a very simple server. In particular, custom error handling would be needed for a production class server. In addition, there are some contrived properties just for demonstration purposes.</P>
<H3>Make Unicode concessions</H3>
<P>At this stage, Python and Unicode dont really work well together. All strings which come from COM will actually be Unicode objects rather than string objects.</P>
<P>To make this code work in a COM environment, the last line of the "Hello" method must become:</P><DIR>
<DIR>
<DIR>
<DIR>
<CODE><P>return "Hello" + " " * self.softspace + str(who)</P></DIR>
</DIR>
</DIR>
</DIR>
</CODE><P>Note the conversion of the "who" to "str(who)". This forces the Unicode object into a native Python string object.</P>
<P>For details on how to debug COM Servers to find this sort of error, please see <A HREF="#debugging">debugging the class</A></P>
<H3>Annotate the class with win32com specific attributes</H3>
<P>This is not a complete list of names, simply a list of properties used by this sample.</P>
<TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=637>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P><B>Property Name</B></TD>
<TD WIDTH="66%" VALIGN="TOP">
<B><P>Description</B></TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P>_public_methods_</TD>
<TD WIDTH="66%" VALIGN="TOP">
<P>List of all method names exposed to remote COM clients</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P>_public_attrs_</TD>
<TD WIDTH="66%" VALIGN="TOP">
<P>List of all attribute names exposed to remote COM clients</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP" HEIGHT=5>
<P>_readonly_attrs_</TD>
<TD WIDTH="66%" VALIGN="TOP" HEIGHT=5>
<P>List of all attributes which can be accessed, but not set.</TD>
</TR>
</TABLE>
<P>We change the class header to become:</P>
<CODE><P>class HelloWorld:</P><DIR>
<DIR>
<P>_public_methods_ = ['Hello']</P>
<P>_public_attrs_ = ['softspace', 'noCalls']</P>
<P>_readonly_attrs_ = ['noCalls']</P>
<P>def __init__(self):</P>
<P>[Same from here…]</P></DIR>
</DIR>
</CODE><H3><A NAME="Registering">Registering and assigning a CLSID for the object</A></H3>
<P>COM requires that all objects use a unique CLSID and be registered under a "user friendly" name. This documents the process.</P>
<H4>Generating the CLSID</H4>
<P>Microsoft Visual C++ comes with various tools for generating CLSID's, which are quite suitable. Alternatively, the pythoncom module exports the function CreateGuid() to generate these identifiers.</P>
<CODE><P>&gt;&gt;&gt; import pythoncom<BR>
&gt;&gt;&gt; print pythoncom.CreateGuid()<BR>
{7CC9F362-486D-11D1-BB48-0000E838A65F}</P>
</CODE><P>Obviously the GUID that you get will be different than that displayed here.</P>
<H4>Preparing for registration of the Class</H4>
<P>The win32com package allows yet more annotations to be applied to a class, allowing registration to be effected with 2 lines in your source file. The registration annotations used by this sample are:</P>
<TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=636>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P><B>Property Name</B></TD>
<TD WIDTH="66%" VALIGN="TOP">
<B><P>Description</B></TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P>_reg_clsid_</TD>
<TD WIDTH="66%" VALIGN="TOP">
<P>The CLSID of the COM object</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP">
<P>_reg_progid_</TD>
<TD WIDTH="66%" VALIGN="TOP">
<P>The "program ID", or Name, of the COM Server. This is the name the user usually uses to instantiate the object</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP" HEIGHT=5>
<P>_reg_desc_</TD>
<TD WIDTH="66%" VALIGN="TOP" HEIGHT=5>
<P>Optional: The description of the COM Server. Used primarily for COM browsers. If not specified, the _reg_progid_ is used as the description.</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP" HEIGHT=5>
<P>_reg_class_spec_</TD>
<TD WIDTH="66%" VALIGN="TOP" HEIGHT=5>
<P>Optional: A string which represents how Python can create the class instance. The string is of format<BR>
[package.subpackage.]module.class</P>
<P>The portion up to the class name must be valid for Python to "import", and the class portion must be a valid attribute in the specified class.</P>
<P>This is optional from build 124 of Pythoncom., and has been removed from this sample.</TD>
</TR>
<TR><TD WIDTH="34%" VALIGN="TOP" HEIGHT=5>
<P>_reg_remove_keys_</TD>
<TD WIDTH="66%" VALIGN="TOP" HEIGHT=5>
<P>Optional: A list of tuples of extra registry keys to be removed when uninstalling the server. Each tuple is of format ("key", root), where key is a string, and root is one of the win32con.HKEY_* constants (this item is optional, defaulting to HKEY_CLASSES_ROOT)</TD>
</TR>
</TABLE>
<P>Note there are quite a few other keys available. Also note that these annotations are <I>not</I> required - they just make registration simple. Helper functions in the module <CODE>win32com.server.register</CODE> allow you to explicitly specify each of these attributes without attaching them to the class.</P>
<P>The header of our class now becomes:</P>
<CODE><P>class HelloWorld:</P><DIR>
<DIR>
<P>_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"</P>
<P>_reg_desc_ = "Python Test COM Server"</P>
<P>_reg_progid_ = "Python.TestServer"</P>
<P>_public_methods_ = ['Hello']</P>
<P>[same from here]</P></DIR>
</DIR>
</CODE><H4>Registering the Class</H4>
<P>The idiom that most Python COM Servers use is that they register themselves when run as a script (ie, when executed from the command line.) Thus the standard "<CODE>if __name__=='__main___':</CODE>" technique works well.</P>
<P>win32com.server.register contains a number of helper functions. The easiest to use is "<CODE>UseCommandLine</CODE>".</P>
<P>Registration becomes as simple as:</P>
<CODE><P>if __name__=='__main__':<BR>
&#9;# ni only for 1.4!<BR>
&#9;import ni, win32com.server.register <BR>
&#9;win32com.server.register.UseCommandLine(HelloWorld)</P>
</CODE><P>Running the script will register our test server.</P>
<H2><A NAME="testing">Testing our Class</A></H2>
<P>For the purposes of this demonstration, we will test the class using Visual Basic. This code should run under any version of Visual Basic, including VBA found in Microsoft Office. Any COM compliant package could be used alternatively. VB has been used just to prove there is no "smoke and mirrors. For information on how to test the server using Python, please see the <A HREF="QuickStartClientCom.html">Quick Start to Client side COM</A> documentation.</P>
<P>This is not a tutorial in VB. The code is just presented! Run it, and it will work!</P>
<H2><A NAME="debugging">Debugging the COM Server</A></H2>
<P>When things go wrong in COM Servers, there is often nowhere useful for the Python traceback to go, even if such a traceback is generated.</P>
<P>Rather than discuss how it works, I will just present the procedure to debug your server:</P>
<B><P>To register a debug version of your class</B>, run the script (as above) but pass in a "<CODE>--debug</CODE>" parameter. Eg, for the server above, use the command line "<CODE>testcomserver.py --debug</CODE>".</P>
<B><P>To see the debug output generated</B> (and any print statements you may choose to add!) you can simply select the "Remote Debug Trace Collector" from the Pythonwin Tools menu, or run the script "win32traceutil.py" from Windows Explorer or a Command Prompt.</P>
<H2><A NAME="Exception">Exception Handling </A></H2>
<P>Servers need to be able to provide exception information to their client. In some cases, it may be a simple return code (such as E_NOTIMPLEMENTED), but often it can contain much richer information, describing the error on detail, and even a help file and topic where more information can be found. </P>
<P>We use Python class based exceptions to provide this information. The COM framework will examine the exception, and look for certain known attributes. These attributes will be copied across to the COM exception, and passed back to the client. </P>
<P>The following attributes are supported, and correspond to the equivalent entry in the COM Exception structure:<BR>
<CODE>scode, code, description, source, helpfile and helpcontext</P>
</CODE><P>To make working with exceptions easier, there is a helper module "win32com.server.exception.py", which defines a single class. An example of its usage would be: </P>
<CODE><P>raise COMException(desc="Must be a string",scode=winerror.E_INVALIDARG,helpfile="myhelp.hlp",...)</CODE> </P>
<P>(Note the <CODE>COMException class supports (and translates) "desc" as a shortcut for "description", but the framework requires "description")</P>
</CODE><H2><A NAME="Policies">Server Policies</A></H2>
<P>This is information about how it all hangs together. The casual COM author need not know this. </P>
<P>Whenever a Python Server needs to be created, the C++ framework first instantiates a "policy" object. This "policy" object is the gatekeeper for the COM Server - it is responsible for creating the underlying Python object that is the server (ie, your object), and also for translating the underlying COM requests for the object. </P>
<P>This policy object handles all of the underlying COM functionality. For example, COM requires all methods and properties to have unique numeric ID's associated with them. The policy object manages the creation of these ID's for the underlying Python methods and attributes. Similarly, when the client whishes to call a method with ID 123, the policy object translates this back to the actual method, and makes the call. </P>
<P>It should be noted that the operation of the "policy" object could be dictated by the Python object - the policy object has many defaults, but the actual Python class can always dictate its operation. </P>
<H3>Default Policy attributes </H3>
<P>The default policy object has a few special attributes that define who the object is exposed to COM. The example above shows the _public_methods attribute, but this section describes all such attributes in detail. </P>
<H5>_public_methods_ </H5>
<P>Required list of strings, containing the names of all methods to be exposed to COM. It is possible this will be enhanced in the future (eg, possibly '*' will be recognised to say all methods, or some other ideas…) </P>
<H5>_public_attrs_ </H5>
<P>Optional list of strings containing all attribute names to be exposed, both for reading and writing. The attribute names must be valid instance variables. </P>
<H5>_readonly_attrs_ </H5>
<P>Optional list of strings defining the name of attributes exposed read-only. </P>
<H5>_com_interfaces_ </H5>
<P>Optional list of IIDs exposed by this object. If this attribute is missing, IID_IDispatch is assumed (ie, if not supplied, the COM object will be created as a normal Automation object.</P>
<P>and actual instance attributes: </P>
<P>_dynamic_ : optional method </P>
<P>_value_ : optional attribute </P>
<P>_query_interface_ : optional method </P>
<P>_NewEnum : optional method </P>
<P>_Evaluate : optional method </P></BODY>
</HTML>

View file

@ -0,0 +1,22 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>win32com Documentation Index</TITLE>
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY LINK="#0000ff" VLINK="#800080">
<H1><IMG SRC="image/pycom_blowing.gif" WIDTH=549 HEIGHT=99 ALT="Python and COM - Blowing the others away"></H1>
<H1>PythonCOM Documentation Index</H1>
<P>The following documentation is available</P>
<P><A HREF="QuickStartClientCom.html">A Quick Start to Client Side COM</A> (including makepy)</P>
<P><A HREF="QuickStartServerCom.html">A Quick Start to Server Side COM</A></P>
<P><A HREF="GeneratedSupport.html">Information on generated Python files (ie, what makepy generates)</A></P>
<P><A HREF="variant.html">An advanced VARIANT object which can give more control over parameter types</A></P>
<P><A HREF="package.html">A brief description of the win32com package structure</A></P>
<P><A HREF="PythonCOM.html">Python COM Implementation documentation</A></P>
<P><A HREF="misc.html">Misc stuff I dont know where to put anywhere else</A></P>
<H3>ActiveX Scripting</H3>
<P><A HREF="../../win32comext/axscript/demos/client/ie/demo.htm">ActiveX Scripting Demos</A></P></BODY>
</HTML>

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

View file

@ -0,0 +1,31 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>win32com</TITLE>
<META NAME="Template" CONTENT="C:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY TEXT="#000000" LINK="#0000ff" VLINK="#0000ff">
<DIR>
<P><!-- Enclose the entire page in UL, so bullets don't indent. --></P>
<H1><IMG SRC="image/pycom_blowing.gif" WIDTH=549 HEIGHT=99></H1>
<H2>Python and COM</H2>
<H3>Introduction</H3>
<P>Python has an excellent interface to COM (also known variously as OLE2, ActiveX, etc).</P>
<P>The Python COM package can be used to interface to almost any COM program (such as the MS-Office suite), write servers that can be hosted by any COM client (such as Visual Basic or C++), and has even been used to provide the core ActiveX Scripting Support. </P>
<UL>
<LI>Note that win32com is now released in the win32all installation package. The <A HREF="../win32all/win32all.exe">installation EXE can be downloaded</A>, or you <A HREF="../win32all/">can jump to the win32all readme</A> for more details. </LI>
<LI>Here is the <A HREF="win32com_src.zip">win32com source code</A> in a zip file. </LI></UL>
</DIR>
<DIR>
<H3>Documentation</H3>
<P><A HREF="ActiveXScripting.html">Preliminary Active Scripting and Debugging documentation</A> is available.</P>
<P>2 Quick-Start guides have been provided, which also contain other links. See the <A HREF="QuickStartClientCom.html">Quick Start for Client side COM</A> and the <A HREF="QuickStartServerCom.html">Quick Start for Server side COM</A> </P>
</P></DIR>
</DIR>
</BODY>
</HTML>

View file

@ -0,0 +1,18 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>Misc win32com Stuff</TITLE>
<META NAME="Version" CONTENT="8.0.3410">
<META NAME="Date" CONTENT="10/11/96">
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\HTML.DOT">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#ffffff">
<H1>Misc stuff I dont know where to put anywhere else</H1>
<H4>Client Side Dispatch</H4>
<P>Using win32com.client.Dispatch automatically invokes all the win32com client side "smarts", including automatic usage of generated .py files etc.</P>
<P>If you wish to avoid that, and use truly "dynamic" objects (ie, there is generated .py support available, but you wish to avoid it), you can use win32com.client.dynamic.Dispatch</P>
<B><P>_print_details_() method</B><BR>
If win32com.client.dynamic.Dispatch is used, the objects have a _print_details_() method available, which prints all relevant knowledge about an object (for example, all methods and properties). For objects that do not expose runtime type information, _print_details_ may not list anything.</P></BODY>
</HTML>

View file

@ -0,0 +1,37 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>The win32com package</TITLE>
<META NAME="Template" CONTENT="D:\Program Files\Microsoft Office\Office\html.dot">
</HEAD>
<BODY LINK="#0000ff" VLINK="#800080">
<H1><IMG SRC="image/pycom_blowing.gif" WIDTH=549 HEIGHT=99 ALT="Python and COM - Blowing the others away"></H1>
<H1>The win32com package </H1>
<FONT SIZE=2><P>This document describes the win32com package in general terms.</FONT> </P>
<FONT SIZE=2><P>The COM support can be thought of as existing in 2 main portions - the C++ support code (the core PythonCOM module), and helper code, implemented in Python. The total package is known as "win32com".</FONT> </P>
<FONT SIZE=2><P>The win32com support is stand-alone. It does not require Pythonwin.</FONT> </P>
<H2>The win32com package </H2>
<FONT SIZE=2><P>To facilitate an orderly framework, the Python "ni" module has been used, and the entire package is known as "win32com". As is normal for such packages, win32com itself does not provide any functionality. Some of the modules are described below:</FONT> </P>
<UL>
<B><FONT SIZE=2><LI>win32com.pythoncom - core C++ support</B>. <BR>
This module is rarely used directly by programmers - instead the other "helper" module are used, which themselves draw on the core pythoncom services.</FONT> </LI>
<B><FONT SIZE=2><LI>win32com.client package<BR>
</B>Support for COM clients used by Python. Some of the modules in this package allow for dynamic usage of COM clients, a module for generating .py files for certain COM servers, etc.</FONT> </LI>
<B><FONT SIZE=2><LI>win32com.server package<BR>
</B>Support for COM servers written in Python. The modules in this package provide most of the underlying framework for magically turning Python classes into COM servers, exposing the correct public methods, registering your server in the registry, etc. </LI>
<B><LI>win32com.axscript<BR>
</B>ActiveX Scripting implementation for Python.</FONT> </LI>
<B><FONT SIZE=2><LI>win32com.axdebug<BR>
</B>Active Debugging implementation for Python</FONT> </LI>
<B><FONT SIZE=2><LI>win32com.mapi<BR>
</B>Utilities for working with MAPI and the Microsoft Exchange Server</LI></UL>
</FONT><P>&nbsp;</P>
<H2>The pythoncom module </H2>
<FONT SIZE=2><P>The pythoncom module is the underlying C++ support for all COM related objects. In general, Python programmers will not use this module directly, but use win32com helper classes and functions. </P>
<P>This module exposes a C++ like interface to COM - there are objects implemented in pythoncom that have methods "QueryInterface()", "Invoke()", just like the C++ API. If you are using COM in C++, you would not call a method directly, you would use pObject-&gt;Invoke( …, MethodId, argArray…). Similarly, if you are using pythoncom directly, you must also use the Invoke method to call an object's exposed method.</FONT> </P>
<FONT SIZE=2><P>There are some Python wrappers for hiding this raw interface, meaning you should almost never need to use the pythoncom module directly. These helpers translate a "natural" looking interface (eg, obj.SomeMethod()) into the underlying Invoke call.</P></FONT></BODY>
</HTML>

View file

@ -0,0 +1,162 @@
<HTML>
<HEAD>
<TITLE>win32com.client.VARIANT</TITLE>
</HEAD>
<BODY>
<H2>Introduction</H2>
<p>
win32com attempts to provide a seamless COM interface and hide many COM
implementation details, including the use of COM VARIANT structures. This
means that in most cases, you just call a COM object using normal Python
objects as parameters and get back normal Python objects as results.
</p>
<p>
However, in some cases this doesn't work very well, particularly when using
"dynamic" (aka late-bound) objects, or when using "makepy" (aka early-bound)
objects which only declare a parameter is a VARIANT.
</p>
<p>
The <code>win32com.client.VARIANT</code> object is designed to overcome these
problems.
</p>
<h2>Drawbacks</h2>
The primary issue with this approach is that the programmer must learn more
about COM VARIANTs than otherwise - they need to know concepts such as
variants being <em>byref</em>, holding arrays, or that some may hold 32bit
unsigned integers while others hold 64bit signed ints, and they need to
understand this in the context of a single method call. In short, this is
a relatively advanced feature. The good news though is that use of these
objects should never cause your program to hard-crash - the worst you should
expect are Python or COM exceptions being thrown.
<h2>The VARIANT object</h2>
The VARIANT object lives in <code>win32com.client</code>. The constructor
takes 2 parameters - the 'variant type' and the value. The 'variant type' is
an integer and can be one or more of the <code>pythoncom.VT_*</code> values,
possibly or'd together.
<p>For example, to create a VARIANT object which defines a byref array of
32bit integers, you could use:
<pre>
>>> from win32com.client import VARIANT
>>> import pythoncom
>>> v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_I4,
... [1,2,3,4])
>>> v
win32com.client.VARIANT(24579, [1, 2, 3, 4])
>>>
</pre>
This variable can then be used whereever a COM VARIANT is expected.
<h2>Example usage with dynamic objects.</h2>
For this example we will use the COM object used for win32com testing,
<code>PyCOMTest.PyCOMTest</code>. This object defines a method which is
defined in IDL as:
<pre>
HRESULT DoubleInOutString([in,out] BSTR *str);
</pre>
As you can see, it takes a single string parameter which is also used as
an "out" parameter - the single parameter will be updated after the call.
The implementation of the method simply "doubles" the string.
<p>If the object has a type-library, this method works fine with makepy
generated support. For example:
<pre>
>>> from win32com.client.gencache import EnsureDispatch
>>> ob = EnsureDispatch("PyCOMTest.PyCOMTest")
>>> ob.DoubleInOutString("Hello")
u'HelloHello'
>>>
</pre>
However, if makepy support is not available the method does not work as
expected. For the next example we will use <code>DumbDispatch</code> to
simulate the object not having a type-library.
<pre>
>>> import win32com.client.dynamic
>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")
>>> ob.DoubleInOutString("Hello")
>>>
</pre>
As you can see, no result came back from the function. This is because
win32com has no type information available to use, so doesn't know the
parameter should be passed as a <code>byref</code> parameter. To work
around this, we can use the <code>VARIANT</code> object.
<p>The following example explicitly creates a VARIANT object with a
variant type of a byref string and a value 'Hello'. After making the
call with this VARIANT the value is updated.
<pre>
>>> import win32com.client.dynamic
>>> from win32com.client import VARIANT
>>> import pythoncom
>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")
>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")
>>> variant.value # check the value before the call.
'Hello'
>>> ob.DoubleInOutString(variant)
>>> variant.value
u'HelloHello'
>>>
</pre>
<h2>Usage with generated objects</h2>
In most cases, objects with makepy support (ie, 'generated' objects) don't
need to use the VARIANT object - the type information means win32com can guess
the right thing to pass. However, in some cases the VARIANT object can still
be useful.
Imagine a poorly specified object with IDL like:
<pre>
HRESULT DoSomething([in] VARIANT value);
</pre>
But also imagine that the object has a limitation that if the parameter is an
integer, it must be a 32bit unsigned value - any other integer representation
will fail.
<p>If you just pass a regular Python integer to this function, it will
generally be passed as a 32bit signed integer and given the limitation above,
will fail. The VARIANT object allows you to work around the limitation - just
create a variant object <code>VARIANT(pythoncom.VT_UI4, int_value)</code> and
pass that - the function will then be called with the explicit type you
specified and will succeed.
<p>Note that you can not use a VARIANT object to override the types described
in a type library. If a makepy generated class specifies that a VT_UI2 is
expected, attempting to pass a VARIANT object will fail. In this case you
would need to hack around the problem. For example, imagine <code>ob</code>
was a COM object which a method called <code>foo</code> and you wanted to
override the type declaration for <code>foo</code> by passing a VARIANT.
You could do something like:
<pre>
>>> import win32com.client.dynamic
>>> from win32com.client import VARIANT
>>> import pythoncom
>>> dumbob = win32com.client.dynamic.DumbDispatch(ob)
>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")
>>> dumbob.foo(variant)
</pre>
The code above converts the makepy supported <code>ob</code> into a
'dumb' (ie, non-makepy supported) version of the object, which will then
allow you to use VARIANT objects for the problematic methods.
</BODY>
</HTML>