How to start activeX
Last updated at 4:17 pm UTC on 14 January 2006
Question: tber July 06, 2004 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: "ServerST10 = new ActiveXObject("BiosServer.BiosServerAdapter")"
Another question: Is it possible to send Mircrosoft command line-commands out of Squeak, for instance to start another program with command line parameters.
I want to script some startup-scripts in Squeak.
Answer: Kenneth Johnsen There is a CommandShell package on SqueakMap that you can use. I haven't tried this on Windows yet, but I am going to soon (to run some Python scripts).
Answer: How to start activeX 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 here you are familiar a bit with tlbimp.exe and the .NET programming model.
.... 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:
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.
PS - To make discovery of the .NET wrapper interface easier, we find using Reflector on any .NET assembly a real time saver. 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).
Answer: Goran Krampe Well, first you have the FFI stuff. Check the 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.
And of course you have OSProcess, check Win32 class categories, class side has at least one example starting solitare.
And finally the last frontier - build your own VM plugin. But that involves more than just Squeak code.
Answer: Torsten Bergmann Have a look at Win32Shell class comment. To startan PE-File, VBScript, Batch, ... use:
Win32Shell new shellOpen: 'c:\myprogram.exe'
There is currently no support for COM Automation. Instead of wasting time 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.