CS-Script 3.20.0

Using COM

Step-by-step tutorial

The following tutorial shows how to call the method of a COM object from the script.

Thre are two possibe approaches to access COM objects: importing type libraries manually or simplified "Single-line COM access" approach. It is recomended to use "Single-line COM access" as it provides seamless access to COM (no manual steps are required). It also allows referencing the COM objects by GUIDS, ProgID or file name (.dll/.ocx) directly from the code. 

Note: the location of the generated Runtime Collable Wrapper file depends on the HideAutoGeneratedFiles setting value (see configuration console for details). The location of this file does not affect the script code in any way.

"Single-line COM access"

Download tutorial source code: interop.zip 
  1. Extract ATLSimpleServ.dll from the zip file.
    This file contains implementation of CTestObjClass CoClass. This class has only one method Test() that displays the message box.     
  2. Create file Interop.cs that contains the following code: 
    //css_prescript com(ATLSimpleServ.dll, SimpleServ, /r);
    using System;
    using SimpleServ;


    class Test
    {
        public static void Main(string[] args)
        {
            CTestObjClass COMObject = new CTestObjClass();
            COMObject.Test();
        }
    }
    Make sure Interop.cs is in the same directory where ATLSimpleServ.dll is located.
  3. Execute the following command in command prompt:
    cscs interop

Output 

The script will display "CTestObj::Test" MessageBox.


Code discussion

The "Single-line COM access" is heavily based on the concept of Pre- and Post-execution scripts.

In this example the script creates the instance and calls the method Test() of the COM object CTestObj

At the start of the execution the script engine executes com.cs script specified with the pre-script directive

//css_prescript com(ATLSimpleServ.dll, SimpleServ, /r);
It instructs the com.cs script to register the COM Server implemented in ATLSimpleServ.dll and to import it's type library into SimpleServ.dll assembly (containing proxy class for the CTestObj).
If you wish you may instruct the script engine to unregister ATLSimpleServ.dll after the execution:
//css_prescript com(ATLSimpleServ.dll, SimpleServ, /r);
//css_postscript com(ATLSimpleServ.dll, /u);

The com.cs script allows importing the COM servers specified not only by the name of the dll implementing it, but also by GUID or ProgID which can be used to  identify the corresponding type library. 

This is an example of accessing the COM server SYSINFO.SysInfo.1 in order to retreive battery status (SysInfo.cs):

//css_prescript com(SYSINFO.SysInfo.1, SisInfoLib);
using
 System;
using SisInfoLib;

class Script
{
    [STAThread]
    static public void Main(string[] args)
    {
        SysInfoClass sysInfo = new SysInfoClass();
        switch (sysInfo.ACStatus)
        {
            case 0:
                Console.WriteLine("Not using AC power");
                break;
            case 1:
                Console.WriteLine("Using AC power");
                break;
            default:
                Console.WriteLine("Unknown AC power status");
                break;
        }
        if (sysInfo.BatteryLifePercent != 255)
            Console.WriteLine("Battery life "+sysInfo.BatteryLifePercent+"%");
        else
            Console.WriteLine("Battery charge status not known");
    }
}

Note that the COM server in this case does not require any registration. This is because it is always present and registered on any Windows with VB controls installed. And this is the reason why you can access it by ProgID (SYSINFO.SysInfo.1 in SysInfo1.cs). 

Alternativelly you can specify the COM server by it's GUID (or TypeLibrary GUID): 

//css_prescript com({6FBA474B-43AC-11CE-9A0E-00AA0062BB4C}, SisInfoLib);

If you do not have VB controls installed the use of the GUID/ProgID can be illustrated by the msxml.cs sample which utilises MS XML parser COM server (%SystemRoot%\system32\msxml2.dll).

Another example of specifying the COM object by it's ProgID is the setEv.cs script. It illustrates how to use VBScript style programming to permanently set environment variable.

Remember that the pre- and post-execution scripts are not executed when the main script is opened for debugging in the VS2003 (this does not apply for VS2005) .


Importing type library manually
Download tutorial source code: interop.zip 
  1. Extract ATLSimpleServ.dll from the zip file.
    This file contains implementation of CTestObjClass CoClass. This class has only one method Test() that pops up the message box.     
  2. Open command prompt. Make sure current directory is the directory where Interop.cs is located. 
  3. Register the COM server form command prompt:
    regsvr32 ATLSimpleServ.dll
  4. Create interop assembly (SimpleServ.dll) with Type Library Importer:
    tlbimp ATLSimpleServ.dll /out:SimpleServ.dll
  5. Create file Interop.cs that contains the following code: 
    using System;
    using SimpleServ;

    class Test
    {
        public static void Main(string[] args)
        {
            CTestObjClass COMObject = new CTestObjClass();
            COMObject.Test();
        }
    }

    The script engine dynamically identifies SimpleServ.dll referenced from the code (using SimpleServ;) and loads it at run-time. Alternatively SimpleServ.dll can be loaded with //css_reference directive: 

    //css_reference SimpleServ.dll;
    using
     System ;

    class Test
    ...
    
      
  6. Execute the following command in command prompt:
    cscs interop

Code discussion

The difference between the "Manual importing" and "Single-line COM access" samples is in the presence of //css_prescript directive. The rest of the code is the same.

Note thet the script engine dynamically identifies SimpleServ.dll referenced from the code and dynamically loads it at the run-time.  Alternatively SimpleServ.dll can be loaded with the //css_reference directive: 

//css_prescript com(ATLSimpleServ.dll, SimpleServ, /r);
//css_reference SimpleServ.dll;
using System ;

class Test
{
    public static void Main(string[] args)
    {
        SimpleServ.CTestObjClass COMObject = new SimpleServ.CTestObjClass();
        COMObject.Test();
    }
}



See Also

Extending the scripting system | Pre- and Post-execution scripts