Squeak SmalltalkJoker Squeak Smalltalk : Image VM OS Application : prevnext COM Activex Wrapper Dot NET Bridge VBScript

I want to start a automations object (Com-Server/ActiveX) out of
Squeak - is that possible? (I work with windows.) - I mean something
like I do in JScript in that way: "ServerST10 = new
ActiveXObject("BiosServer.BiosServerAdapter")"
Another similar question: Is it possible so send Mircrosoft command
line-commands out of Squeak - for instance to start another program
with command line parameters.
It's because I want to script some startup-scripts in Squeak

have a look at Win32Shell class comment. To start
an PE-File, VBScript, Batch, ... use:

  Win32Shell new shellOpen: 'c:\myprogram.exe'

Well, first you have the FFI stuff. Check class comment of Win32Shell
to play some.
Then you can use FFI yourself to easily call .dlls, haven't played much
myself with that - but you can see how it is done in the FFI example
classes.

There is currently no support for COM Automation.
Instead of wasting time for wrapping COM in Squeak
it is much easier to call a VBScript or use a
native Smalltalk like ST/MT or Smallscript for
windows specific stuff.
Also have a look at the CommandShell package
on SqueakMap. It's usefull for command line stuff.

We used Squeak on the job to automate COM components quite
successfully.  We didn't build a COM interface, but we did build a .
NET interface.  So it seems a bit like technology soup, but if you use
tlbimp.exe in the .NET Framework SDK (I believe) you can generate a .
NET wrapper around a COM object/control.  Then using the Squeak .NET
bridge on SqueakMap you can then instantiate and automate your COM
object.  Yes, it does indeed work (at least for our COM components we
tried it with).
If you need more specific examples I can provide those in a follow-up
email.  I am assuming you are familiar with tlbimp.exe and the .NET
programming model a bit here.
Regards,
John

To wrap a COM or ActiveX object with .NET and automate it in Squeak
you will need to do the following steps.  First you need to ensure you
have the .NET Framework Runtime Redistributable and the .NET Framework
SDK installed to do what I am about to show you.  Here's some URLs if
you need to download and install:

  1. .NET Runtime Redistributable: http://tinyurl.com/95zt
  2. .NET SDK: http://tinyurl.com/97x7

Basically you only need to install the .NET Runtime to use the Squeak .
NET interface and to automate .NET objects, but to do the COM
automation you need a small utility out of the .NET SDK to wrap the
COM object so you are stuck getting and installing 100+ Megs of the
SDK just to make this work.  Sorry about that part.

*SIDEBAR* : Interestingly enough, once you have the relatively small .

NET Runtime installed, Microsoft gives away the C#, C++, J#, and VB.
NET compilers in the runtime redistributable so you can write, build,
and run .NET applications with your favorite text editor and command-
line builds without buying a thing from anyone.  In fact, any machine
that has the .NET runtime installed on it (which are many these days)
is essentially a development box since the compilers come with .NET
for free.
Now that you have .NET installed you can install the Squeak .NET
interface (just to get software installation activities completed).
Open Package Loader and find and install the Squeak/.NET Bridge
package.  You can test your installation to ensure you have both .NET
and the Squeak .NET bridge installed correctly by opening a workspace
and printing the following line:

  DotNet ArrayList new count

It should create a new .NET ArrayList (which has no elements) and
print its count (the .NET equivalent of "size").  Of course, zero
should be printed.
If you have all this successfully, you are well on your way to
automating your COM object.  I will demonstrate the wrapping of a COM
object and automating in Squeak in a subsequent post since this
posting is more general in nature.

Now on to wrapping a COM object and automating it in Squeak.  For this
demonstration I will choose a rather boring COM object because I know
it generally is installed on any Windows machine.  We will automate
the Windows Script Host objects, an instance of the WshShell class in
particular.
First, we have to get the COM object wrapped with .NET wrappers before
this will be useful.  You must open a command prompt and ensure you
are in the Microsoft.NET\SDK\v1.1\bin folder (generally under
c:\Program Files) or you have a path setup to this folder.  We want to
run tlbimp.exe (in this folder).  This is the Type Library to Assembly
Converter program from the Microsoft .NET SDK. It basically adapts the
COM interface to a .NET one.  As a matter of definition, ..NET DLLs
are called "assemblies" (not entirely correct, but good enough for
this discussion).
Now that you are in the right folder let's create the .NET wrapper for
the WSH COM objects.  Depending on your computer your WSH DLL may be
in a different location, but on my Windows XP computer it is the
following file: C:\WINDOWS\System32\wshom.ocx
So I will run the following command:

  tlbimp c:\windows\system32\wshom.ocx

This will generate a file called "IWshRuntimeLibrary.dll" in the
current folder.

Move this file to your squeak default folder for ease of use.  That's
all we needed the Microsoft .NET SDK for at this point.
If you browse the Microsoft SDK documentation you will see that there
is a WshShell class.  To access this class in Squeak we first need to
load this new assembly we just created.  In a workspace do the
following:

  DotNet Assembly loadFrom: 'IWshRuntimeLibrary.dll'.

NOTE: You will get warnings about unknown selectors when using the .
NET bridge because  nearly everything in this bridge is implemented
via the magic of DNU. With nearly 1600 classes in the .NET framework
we took this short cut.  Just proceed through the warnings.
Now this .NET wrapper is loaded in the .NET execution environment.
Next we instantiate an instance of the WshShell class as follows:

  shell := DotNet WshShellClass new.

Why not just WshShell?  WshShell is the interface and WshShellClass is
the class that implements this interface.  This is a common idiom when
using wrapped COM objects via .NET (not a Squeak .NET bridge idiom).
Now that we have an instance of COM object "WScript.WshShell" in hand,
let's send it the Popup message to get a messagebox on the screen.
Here's the signature of that message from the MSDN documentation:

  intButton = object.Popup(strText,[nSecondsToWait],[strTitle],[nType])

So in Smalltalk we say:

  buttonPressed := shell popup: 'Hello from Squeak' secToWait: 5
    title: '.NET Bridge Demo' type: 0.

As you will notice, with the Squeak / .NET Bridge you have to invent
keywords for each argument.  Here, I used explaining keywords, but you
can write this as:

  shell popup: with: with: with:

if you like.  It really doesn't matter what you make your keywords,
just get the function name correct up front.  Additionally, the .NET
bridge in Squeak is case insensitive, so it doesn't matter if you call
POPUP, popup, or Popup.  Lastly, you may notice the signature of Popup
had optional arguments.  Well, guess what?

 .NET does not support this notion of COM and IDispatch so you must
 provide all arguments.  (Again -- not a Squeak / .NET bridge issue).

If you need more examples and/or more info on using the bridge go to
our wiki on this technology at:
 
http://www.saltypickle.com/squeakDotNet or write me.

Regards,
John

PS - To make discovery of the .NET wrapper interface easier we find
using Reflector on any .NET assembly a real time save.  You can get a
copy of reflector at: http://www.aisto.com/roeder/dotnet/.  It is like
OleView, but for ..NET assemblies (not COM DLLs).