TypeLib Info According to Active State


Background

ActiveState became partners with Microsoft back in 1995. AS gave MS the copyright for Win32::OLE.pm back then and the code for it has had only minimal changes, mostly done in 1997-1999 by Jan Dubois and Gurusamy Sarathy, while working at AS.

If you have tried to get TypeLib Information from within a Perl or Python script, you have noticed that the COM exports from TLBInf32.dll are unavailable--you will get an "interface unsupported error." The main purpose of this article is to show how the AS coders get around this in Perl using some unsupported/undocumented code.

TLBInf32.dll (Library: TLI) is Unsupported in AS Perl (prior to Build 819: 8-26-2006)

Here is how I tried to use the TLI object in Perl. I start by using TLViewer to get the creation string for TLI.TLIApplication as Perl code. You can see the screenshot here:

TLI Creation Code

use Win32::OLE;
my $Obj = Win32::OLE->new('TLI.TLIApplication', \&OleQuit) ||
        die("could not create Obj \n", Win32::OLE->LastError,"\n");


sub OleQuit
{
my $self = shift;
undef $self;
}

As expected, you get these errors:
could not create Obj
Win32::OLE(0.17) error 0x80004002: "No such interface supported"

Cry Foul, you say?

Its not my place to comment on why this library is not supported in neither Perl nor Python. Nevertheless: let's say that all fingers point at Microsoft-- they have pressured ActiveState to obfuscate the aquisition of TypeLib Information for both their major script interpreters! The good news is that there is a workaround, though its a dirty, filthy hack. I can understand that private methods using basic Win32 API interfaces are employed from within the Win32::OLE code, but why do Perl AND Python both fail to instantiate TLI objects?

AS TypeLib Info Tricks


Search the Registry for a TypeLib

You can use various filters to search the registry by HelpString, CLSID, or InprocServer32. This method is exported from Win32::OLE::Const:
use Win32::OLE qw(in with);
use Win32::OLE::Const ;
Win32::OLE->Option(Warn => 1);
# Microsoft Excel 9.0 Object Library
my $Lib = '';
use Data::Dumper;

my @Library;

# enum the registry TypeLib subkeys
Win32::OLE::Const->EnumTypeLibs(sub {
my ($clsid,$title,$version,$langid,$filename) = @_;
return unless $version =~ /^([0-9a-fA-F]+)\.([0-9a-fA-F]+)$/;
my ($maj,$min) = (hex($1), hex($2));
push @Library, [$clsid,$title,$maj,$min,$langid,$filename];
});

# sort it by HelpString if you like
#@Library = sort {lc $a->[1] cmp lc $b->[1]} @Library;

# how many libs are there?
print $#Library, "\n";

my %Libs;

foreach my $LibAR ( @Library) {
if ( $$LibAR[1] =~ /excel/ig) {
my ($clsid,$title,$maj,$min,$langid,$filename) = @$LibAR;
push @{$Libs{$clsid}}, ($title,$maj,$min,$langid,$filename);
#print "CLSID=", $clsid, "Vers=$maj\.$min \n";
}
}
print Dumper \%Libs;

On my system this yields 3 typelibs.

Appendix


Problem Solved

Thanks to Jan Dubois this problem has been fixed in Perl starting in Build 819. Due to Jan's diligence of following posts in the ActivePerl lists, this issue came to his attention. He found some unusual behavior in TLBInf32.dll in exporting interfaces which was incompatible with the standard approach used at AS. Thankfully, he followed through, patched Win32::OLE, and got the release out ASAP. We can say that this trouble is behind us starting September 2006.

Notes on Win32::OLE

The heart of the OLE Module is OLE.xs.

The above code has 6800 lines! Notice the MS copyright. According to Jan Dubois, most
of it was coded before he joined AS.

The Active State OLE Browser

You can find more exotic, hidden methods from Win::OLE:: modules for getting TypeLib info by snooping through the famous OLE Browser (browser.dhtml). I recall that this project works once you enable PerlScript in your web server. Fire up your favorite text editor and do some code reading.

Win32::OLE Supporting Modules