owenG
home learn tableau about
divider
legalific swsom swsom diagram swapps ahk ue








swsom wrapper
[Overview] Application - CurrentNote DB - Notes ocrBase - OpenTranscripts Permission - Views
 
Download :: Diagram
swsom wrapper

Approach

This project grew out of my attempt to work with the Summation API via C#, which was doable but not easy or pretty. With the inability to perform early binding, the Summation .exe needs to be accessed via late binding - see Binding for Office automation servers with Visual C# .NET for C# usage with the two types of bindings. Also see Programming Office Applications Using Visual C# to get an idea of other issues that may be present when dealing with automation via C#. Both articles are oriented toward MS Office but hold useful information for other scenarios, including C#-->Summation.

For example, wanting to open the OCR log could be performed with the below within the Summation scripting window:

vs
    Img.OCR.ViewLog()

and not much worse in Visual Basic:

VB
    Set swObj = CreateObject("Summation.Application")
    swObj.Img.OCR.ViewLog()    

while doing the same in C# is a tad more complicated (and the below example doesn't even involve an entry point with parameters):

C#
    Type summationType = Type.GetTypeFromProgID("Summation.Application");
    object swObj = Activator.CreateInstance(summationType);
    object swImgMethod = swObj.GetType().InvokeMember("Img", BindingFlags.InvokeMethod, null, swObj, 
        null);
    object swOcrMethod = swImgMethod.GetType().InvokeMember("OCR", BindingFlags.InvokeMethod, null, 
        swImgMethod, null);
    swOcrMethod.GetType().InvokeMember("ViewLog", BindingFlags.InvokeMethod, null, swOcrMethod, null);        

On the other hand, after adding a reference to swsom.dll, the C# effort can be minimal:

C#
    using swsom;
    ...
    sw.Img.OCR.ViewLog();

And in VB:

VB
    Imports swsom
    ...
    sw.Img.OCR.ViewLog()

Presumably there will be a performance hit but such consequences must be weighed against any alternative method of accomplishing your goal.


Parsing & Cleanup

In order to create the code, I wrote an app that processed the xml file (sumscript.xml) that holds the scripting help file documentation and as output created several .vb files:

  • create two .vb files (one for items marked as Properties in the sumscript, another for Methods, were later manually combined into a single file) for each object, with appropriate nested Class statements
  • for each entry point
    • if it was defined as Method in sumscript, read the Syntax value and write out as a VB Function if it returned a value, as a Sub otherwise
    • it Property, write out as a Read-Write VB Property
    • initially set as Shared i.e. non-instance
    • read the Description, Notes, Syntax values from sumscript and prepend to each method/property as XML comments
    • try to keep original name if possible, surrounding VB keywords with square brackets e.g. [keyword] where necessary
    • for v1.1, all Optional parameters were removed since they had, necessarily, been defined in v1.0 with arbitrary default values. In some cases these values would actually have negative effects, overriding the 'default' values embedded within the application. The lack of real support for optional parameters in C# also presented problems.
      • those Subs and Functions that had Optional parameters were re-written to have multiple overloads, one for each combination of required and optional parameter(s)
    • where it proved more efficient, modify the original sumscript file and re-run the parser application

    After the initial parsing, each .vb file needed to be reviewed and corrected as necessary. In some cases there were mistakes or inconsistencies in the original documentation that were persisted to the generated code while in other cases the code simply needed to be re-formatted to be more VB friendly.

    Some of the fixing steps involved:

    • looking at each Property and trying to determine if indeed they should be both Read and Write. For some the documentation contained a reference but many did not and I made an educated guess when deciding to set as ReadOnly. The original Set accessor was only commented out though, so it can easily be revived if appropriate (assuming the syntax in the Set wasn't later changed)
    • moving the base Application class into its own child-class, only done so that the Intellisense would be less cluttered at the base level
    • creating a working configuration of those classes that were Collections. Generally this meant changing the members into instance classes and it is quite possible the implementation will change in the future - the goal for now is 'good enough'. They are not enumerable right now and therefore do not act as a true collection
    • conform any Properties that used parameters, a syntax that is generally not supported in C#. Many properties were re-formatted as Functions but still lie with in the 'Properties' region code of a given .vb file
    • an occasional helper method was introduced here and there

Notes

* The XML comment section for each entry point that was read from the sumscript.xml is prepended with either a 'p_' or a 'm_', indicating that it was originally documented as either a Property or Method, regardless of how it is implemented in the .vb (some Properties are actually written as VB.Net Functions). I'm not sure there is much reason for keeping these, especially since I'm suspect the actual implementation on the C++ is not necessarily consistent, but I figure they can later be removed easily enought via a Global Find and Replace.

* VB.net doesn't honor paragraph marks in XML documentation. If I recall correctly the IL code is correct but Visual Studio (2005 and 2008 at least) doesn't honor the <para> tag when it comes to VB. For that reason I added a '- - - - -' prefix before the SYNTAX section in the comments, so that it would be at least somewhat separated from the other text when displayed in VB.Net Intellisense.

* Many of the entry points were originally defined as properties that took parameters. This is permitted in VB but not in C#, indexers aside. I re-wrote some of these as Functions instead but others are still coded as parameterized Properties. These will accessed from swsom as normal from VB (and appear with original name in Intellisense) but in C# they will be replaced by accessor methods i.e. the Property name will need to be prepended with either get_ or _set_ as appropriate. One such example is discussed here.

* There is a COM Reference in the swsom .vbproj to ADODB version 2.7. Both my testing and research indicate this will usually not cause any problems in terms of prerequisites but apparently some developers have had dependency issues in certain environments. The result is an error from .Net indicating that the ADODB assembly must be installed in the Global Assembly Cache (GAC), even though it may already be there. I only ran into that particular error with a project involving ClickOnce deployment and the fix was simply to ensure a copy of ADODB.dll was present in the same directory as the deployed swsom.dll. An alternative, given that the source code can be manipulated any which way, would be to remove the ADODB reference entirely. As a result the Clone and Cull methods in DB/DBGrid would need to be commented out or rewritten.