Think about Loose Coupling | |
PerlMonks |
Basically what you want to be able to do is:
Where HelloDot.HelloWorld is a .NET assembly registered in the system to look/act/smell like a regular COM component. The following are preliminary setup steps that do not require explanation:perl -e "use Win32::OLE; $hl = new Win32::OLE('HelloDot.HelloWorld') o +r die $!; $hl->SayHello();"
After mucking with your PATH, you should create a key file like this:
This creates a 'key pair' file which contains a public and a private key for entering the .dll we are about to create into the GAC, the Global Assembly Cache. Think of it as a Windows registry for .NET assemblies. There is a way to separate the public key part from the private one (using sn -p) in case you are interested. (Note: I'm not sure why this thing didn't offer to allow me a choice of ciphers or allow me to choose my own entropy engine. I remember reading that it is using SHA1 or something, but I don't know.)sn -k personality.snk
The first think you will notice when you run an example with the .NET framework is that it is terribly slow. A simple 'Hello World' takes about three seconds to run every time. It seems obvious to me that this thing was not written for quick one-liner-like execution, so be warned. Copy the following hello.cs file and compile it:
You need a constructor with no params for the .NET assembly to be called like a regular COM component (as with Win32::OLE). There is some kind of wrapper that M$soft creates to allow COM components to interact with .NET assemblies and the constructor is necessary to make that happen. If you are interested on the why, more information on that is here. The only problem with this is that a third party .dll is probably not going to have this constructor, so at that point you will have to create a wrapper class that does have it before you try this.using System; using System.Reflection; [assembly:AssemblyVersion("1.0.0.0")] [assembly:AssemblyKeyFile("personality.snk")] namespace HelloDot { public class HelloWorld { public HelloWorld(){ //no param constructor for COM } public void SayHello(){ Console.WriteLine("Hello from DOT NET"); } } }
Anyway, you need to compile this into a .dll like so:
If you go back to to the hello.cs code, you will notice the funny lines before the namespace that stand out like a sore thumb: assembly:AssemblyVersion...yadda,yadda. These instructions tell the compiler that you are creating an assembly you are intending to share. If you remove the lines and recompile you will notice that the .dll becomes a little smaller. Remember to put it back in and recompile before you continue this tutorial.csc /t:library /out:hellodot.dll hello.cs
If the .dll compiled okay you now have to register it:
There is one more thing to do. Your .NET assembly still needs to look and act like a regular COM component. Normal COM components (i.e. Excel.Application, Microsoft.XML, etc.) are registered with regsvr32. This puts their GUIDs in the Window's Registry (see HKEY_LOCAL_MACHINE/Software/Classes for the ones you've got). Not so in this case. You need to use regasm.exe in order to 'register' your .NET .dll to be usable by everybody outside of the .NET camp:gacutil /i hellodot.dll
With all of this being done, you should be able to call the following:regasm hellodot.dll
perl -e "use Win32::OLE; $hl = new Win32::OLE('HelloDot.HelloWorld') o +r die $!; $hl->SayHello();"
You may read from various online sources that it is unncessary to load the assembly into the GAC for you to call it as a COM component, but this does not (at least for me) seem to work. Without registering in the GAC I had to copy the .dll to the Windows/System32 directory just to get it to work for the Window's Scripting Host. Win32::OLE simply could not find the bugger until I registered it in the GAC.
Summary:
Are you are asking yourself, "why is any of this important?" Well, it seems that the only other way to get Perl on Windows to interact with .NET is to pony up cash for Visual Studio.NET and Visual Perl. The above tutorial offers a (relatively) quick and (depending on your threshold) painless way to interoperate with .NET components.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Calling .NET Assemblies with Win32::OLE
by dawook (Initiate) on Dec 07, 2007 at 22:52 UTC | |
by srirajpaul (Initiate) on May 12, 2008 at 13:03 UTC | |
by Anonymous Monk on Jun 24, 2011 at 05:12 UTC | |
Re: Calling .NET Assemblies with Win32::OLE
by xtan (Initiate) on Apr 09, 2010 at 16:10 UTC | |
Re: Calling .NET Assemblies with Win32::OLE
by Anonymous Monk on Mar 15, 2011 at 16:42 UTC | |
by Anonymous Monk on Mar 26, 2012 at 07:19 UTC |