Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
This is a tutorial for calling a .NET assembly via Win32::OLE. I was looking for such a tutorial on the web and previously at PerlMonks but didn't find anything, so I elected to research the issue, get a quick example working, and submit it.

Basically what you want to be able to do is:

perl -e "use Win32::OLE; $hl = new Win32::OLE('HelloDot.HelloWorld') o +r die $!; $hl->SayHello();"
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:

  • Step 1: You will have to install both the .NET Framework and the .NET SDK on your machine (type .net framework/sdk download in Google)
  • Step 2: The installer does not set your path, so you will have to add the following to be able to reach gacutil.exe, regasm.exe, csc.exe (my cheezy example was written in C#), etc.: C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\

    After mucking with your PATH, you should create a key file like this:

    sn -k personality.snk
    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.)

    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:

    using System; using System.Reflection; [assembly:AssemblyVersion("")] [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"); } } }
    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.

    Anyway, you need to compile this into a .dll like so:

    csc /t:library /out:hellodot.dll hello.cs
    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.

    If the .dll compiled okay you now have to register it:

    gacutil /i hellodot.dll
    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:
    regasm hellodot.dll
    With all of this being done, you should be able to call the following:
    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.

    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.

    In reply to Calling .NET Assemblies with Win32::OLE by InfiniteSilence

    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post; it's "PerlMonks-approved HTML":

    • Are you posting in the right place? Check out Where do I post X? to know for sure.
    • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
      <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
    • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
    • Want more info? How to link or or How to display code and escape characters are good places to start.
  • Log In?

    What's my password?
    Create A New User
    Domain Nodelet?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others perusing the Monastery: (2)
    As of 2022-10-01 18:52 GMT
    Find Nodes?
      Voting Booth?
      My preferred way to holiday/vacation is:

      Results (3 votes). Check out past polls.