Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Excerpt
hiddentrue

script Windows ActiveX and COM components with Groovy

Note
titleUnder Construction

The Scriptom documentation is changing to reflect the new Maven build and artifacts.
This is going to take some time. In the meantime, please take what you read with a grain of salt,
and pardon the messiness.
Rest assured that while there will be some restructuring of the documentation, the previous
builds will still be available for anyone who needs them, ongoing, indefinitely.

...

Installation

Scriptom is part of the Windows Installer. If you are running Groovy scripts on Windows, you are all set.

...

You can add Scriptom to a Maven project. Because there is JNI involved, it isn't quite as simple as adding a dependency, but it is doable. Need to come up with an example of creating an assembly with GMaven.

  1. Add the Scriptom dependency to your Mavenproject.

    Code Block
    
    <dependency>
      <groupId>org.codehaus.groovy.modules.scriptom</groupId>
      <artifactId>scriptom</artifactId>
      <version>1.6.0</version>
    </dependency>
    
  2. Add the Jacob JAR dependency. This JAR must be loaded only once, so if you are working in a server application like Tomcat or GlassFish, you need to ensure that Jacob's JAR is only loaded by the system classloader. Need more explicit instructions on this...

    Code Block
    
    <dependency>
      <groupId>net.sf.jacob-project</groupId>
      <artifactId>jacob</artifactId>
      <version>1.14.3</version>
      <type>jar</type>
    </dependency>
    
  3. Jacob requires a DLL. It's a JNI project, after all. But Jacob actually supports two versions of the DLL it needs, one for 32-bit x86 systems, and one for the AMD x64 architecture (works with 64-bit Intel chips too). The easiest way to get this to work is to put both DLLs somewhere on the system path. Jacob will automatically pick the one it needs. Need to detail the other ways to specify the Jacob DLL.

    Code Block
    
    <dependency>
      <groupId>net.sf.jacob-project</groupId>
      <artifactId>jacob</artifactId>
      <version>1.14.3</version>
      <type>dll</type>
      <classifier>x64</classifier>
    </dependency>
    <dependency>
      <groupId>net.sf.jacob-project</groupId>
      <artifactId>jacob</artifactId>
      <version>1.14.3</version>
      <type>dll</type>
      <classifier>x86</classifier>
    </dependency>
    

...

Install the jar file and DLL file(s) into your project, and optionally install an update from Microsoft:

  1. Add the Scriptom jar file (scriptom-1.5.4bX-XX.jar) into your Java classpath.  It contains both Scriptom and Jacob class files, so you must not include jacob.jar.

    Warning

    Scriptom contains a full (current) version of the Jacob library. If you are using Jacob directly elsewhere in your project, remove all references to it and use the version built in to Scriptom.

  2. Copy both Scriptom-1.5.4bX-XX.dll files to somewhere on your java.library.path. (usually somewhere on the system 'PATH').

    Info

    The Scriptom DLL naming convention allows multiple versions of Scriptom to run on the same machine. However, you can only run a single version of Scriptom JAR in any given project.

  3. To avoid the dreaded java.lang.UnsatisfiedLinkError, download and install one of the following updates from Microsoft: Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)or Microsoft Visual C++ 2005 SP1 Redistributable Package (x64). Scriptom doesn't support the  IA-64 (Itanium) architecture at this time, mainly due to lack of interest. If you are wondering about the different processor architectures, check out the x86-64 wiki. It is usually necessary to install these updates on Windows Server 2003 and Windows 2000, and we've found that it may also be necessary for Windows XP and even Vista.

    Note

    A project can only use one version of Scriptom at a time. If you have installed Groovy using the Groovy Windows Installer, you must remove any versions of Scriptom JAR files or replace them with the latest version. A version of Scriptom is installed as part of the Groovy Windows Installer installation.

    Scriptom 1.5 is not supported for Groovy 1.0 and earlier (Scriptom 1.2 is still available). 

Building from Source

The project source is managed by Subversion. The projects are already set up to work with Eclipse, but it isn't hard to get them working with other IDEs, and you can get by with Notepad. The project trunk is located at http://svn.codehaus.org/groovy/modules/scriptom/trunk. This is a Maven build. Because the tests are dependent on Windows technologies, there are some rather strange software requirements:

...

To build, use the following command line:

Code Block

C:\work\groovy\modules\scriptom\trunk>mvn clean install

...

You start by creating an ActiveXObject with the prog-id for SpVoice. Now you can call any of the methods it supports. By default, SpVoice will block until it is done speaking, but we're also going to have it speak asynchronously and wait until it is done.

Code Block

import org.codehaus.groovy.scriptom.*
import static org.codehaus.groovy.scriptom.tlb.sapi.SpeechVoiceSpeakFlags.*
import static org.codehaus.groovy.scriptom.tlb.sapi.SpeechRunState.*

//Definitive proof that you CAN talk and chew gum at the same time.
Scriptom.inApartment
{
  def voice = new ActiveXObject('SAPI.SpVoice')

  //This runs synchronously.
  voice.speak "Hello, GROOVY world!"

  //This runs asynchronously.
  voice.speak "GROOVY and SCRIPT um make com automation simple, fun, and groovy, man!", SVSFlagsAsync
  while(voice.Status.RunningState != SRSEDone)
  {
    println 'Chew gum...'
    sleep 1000
  }
}
println 'Speaker is done.'

...

This next example displays the COM interfaces that SpVoice supports (within the SAPI library only):

Code Block

import org.codehaus.groovy.scriptom.*;
import org.codehaus.groovy.scriptom.tlb.sapi.SpeechLib;

Scriptom.inApartment
{
  def voice = new ActiveXObject('SAPI.SpVoice')
  SpeechLib.interfaces.each {name, iid -> if(voice.supportsInterface(iid)) println "SpeechLib.$name - $iid"}
}

...

The Least You Need to Know about COM

Excerpt Include
The Least You Need to Know about COM
nopaneltrue
The Least You Need to Know about COM
nopaneltrue

COM Data Types in Scriptom

Excerpt Include
COM Data Types in Scriptom
nopaneltrue
COM Data Types in Scriptom
nopaneltrue

COM Methods and Properties in Scriptom

Excerpt Include
COM Methods and Properties in Scriptom
nopaneltrue
COM Methods and Properties in Scriptom
nopaneltrue

Passing Values by Reference (in-out)

Excerpt Include
Passing Values by Reference (in-out)
nopaneltrue
Passing Values by Reference (in-out)
nopaneltrue

COM Events

Excerpt Include
COM Events
COM Events
nopaneltrueCOM Events

All About Arrays

Excerpt Include
All About Arrays
All About Arrays
nopaneltrueAll About Arrays

Examples

Here is a simple example that uses the Microsoft ScriptControl to evaluate a JScript expression.   This is a very indirect way to add 2 and 2.

Code Block

import org.codehaus.groovy.scriptom.*

Scriptom.inApartment
{
  def scriptControl = new ActiveXObject("ScriptControl")
  scriptControl.Language = "JScript"
  println scriptControl.Eval('2.0 + 2.0;')
}

...

Consuming Visual Basic 6 (VB6) and Visual Basic.NET COM-enabled DLLs.

Articles

Include Page
Scriptom Articles
Scriptom Articles

Post Scriptom

All known (unresolved) issues and feature requests are listed in the Scriptom Jira database.

...

Recent builds of Scriptom can be found here. Older versions are archived:

Include Page
Scriptom Archive
Scriptom Archive

Progids

Scriptom uses late binding. Visual Basic and VBA uses early binding by default, but they also support late binding (with CreateObject). If you are translating working Visual Basic code and if your Scriptom code fails at the point where you've got your call

Code Block

    ActiveXObject oSDO = new ActiveXObject("SageDataObject140.SDOEngine")

 (or whatever your object is) with an error message

Code Block

Caught: org.codehaus.groovy.scriptom.ActiveXObject$CreationException:
Could not create ActiveX object: 'SageDataObject140.SDOEngine'; Can't
get object clsid from progid 

...

So you need to go and look in the registry to find what it might be. One way to do this is with Microsoft's new Powershell cmd utility which you can download from the ms web site. Install this and run the command line

Code Block

dir  REGISTRY::HKEY_CLASSES_ROOT\CLSID -include PROGID -recurse | foreach {$_.GetValue("")} 

...

Alternatively if you have used the scriptom utility ExtractTlbInfo.groovy to generate name maps for the com object you could read the source code for the (in my case SageDateObject140.java) class and you might find some code and/or comment like this:

Code Block

/**
   * A {@code Map} of CoClass names to prog-ids for this type library.<p>
   *
   * Note that some objects that support events do not publish a prog-id.
   * This is a known limitation of this library that we hope to resolve in
   * a future release.<p>
   *
   * Supported prog-ids:
   * <ul>
   *   <li><b>SDOEngine</b> = SDOEngine.14</li>
   * </ul>
   */
  public final static Map progIds;
  static
  {
    TreeMap v = new TreeMap();
    v.put("SDOEngine", "SDOEngine.14");
    progIds = Collections.synchronizedMap(Collections.unmodifiableMap(v));
  }

...