I thought I'd summarise my conclusions here, on the off chance they may 
help someone else with a similar problem... Although unfortunately, I 
offer no solutions! ;-)

Jeff Cohen wrote:
> 
> Sounds like have a COM object but not a scriptable COM object.  Only COM 
> objects which implement the IDispatch interface can be called from 
> late-binding scripting languages like VBScript and JScript.
> 
> VB (not VBScript) is able to use early-binding COM objects as well as 
> late-binding ones, so that's why you got a "false positive" by using VB 
> instead of VBScript.

Actually, that is not the problem here. The COM objects *do* implement 
IDispatch:
    irb(main):004:0> p hfm.ole_methods
    [QueryInterface, AddRef, Release, GetTypeInfoCount, GetTypeInfo, 
GetIDsOfNames, Invoke, ...

The problem seems to be that a key method (OpenApplication) which is 
required to obtain references to other COM objects does so by using OUT 
parameters which are declared to be of type Unknown, rather than the 
actual type. Here is the method signature again:
  # VOID OpenApplication
  # method OpenApplication
  #   BSTR arg0 --- bstrClusterName [IN]
  #   BSTR arg1 --- bstrProduct [IN]
  #   BSTR arg2 --- bstrApp [IN]
  #   UNKNOWN arg3 --- ppIUnkServer [OUT]
  #   UNKNOWN arg4 --- ppIUnkSession [OUT]

As Ruby (along with VBScript, JScript, etc) is a dynamically typed 
language, there is no way to declare the desired type of the arg3 and 
arg4 parameters passed into (and out of, via ARGV) the OpenApplication 
method, as you can do in VB:
    Dim session as HsvSession

Passing an ordinary Object (Object.new) for arg3 and arg4 allows the 
method call to succeed, but the returned objects can't be used to call 
any COM methods because WIN32OLE does not have any type info for them.

I think the reason the types are declared as Unknown in this instance is 
because the type of the returned object (HsxServer and HsvSession 
respectively) are defined in different (and separate) type libraries. 
Exactly why this should be the case, I've no idea.

There are two ways I can see that this problem might still be overcome, 
but both are beyond me:
1) Create a dummy object of the correct COM type, i.e.

    server = WIN32OLE.new('Hyperion.HsxServer')
    session = WIN32OLE.new('Hyperion.HsvSession')
    hfm.OpenApplication(arg0, arg1, arg2, server, session)
    server = ARGV[3]
    session = ARGV[4]

This seemed quite promising, in that the call appeared to succeed, and 
the returned objects had the necessary type library info attached. 
However, any attempt to use these objects subsequently led to a "HRESULT 
error code:0x80020009 Exception occurred" error. I'm not sure what is 
causing this error (something to do with reference counting maybe?), but 
I was unable to get past it.

2) Enhance WIN32OLE to somehow allow type information to be added to an 
object once it has been created. What I'm getting at here is that after 
a successful call to OpenApplication using Object.new, I know that 
ARGV[3] is actually of type HsxServer and ARGV[4] is of type HsvSession, 
but WIN32OLE does not. If I could somehow assign type information to 
these out parameters that currently lack it, I could then call the COM 
methods on these objects.

I'm not sure how much effort this second option would be, but I figure 
this problem is probably too specialised to warrant the effort. 
Therefore, I'll probably end up working around this via VB (arghh!) :-(

Cheers,

Adam

-- 
Posted via http://www.ruby-forum.com/.