Last updated at 12:39 pm UTC on 17 January 2006
Harvested from the list 7-7-2004:
John R. Pierce wrote:
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
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 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).