views:

51

answers:

0

Hi!

I am trying to call some COM method which uses another COM object as argument via Powershell but I can't get it to work.

$dbc = New-Object -ComObject "BMS.MOL.DBConnector"
$client = New-Object -ComObject "BMS.MOL.Client"

Calling

$dbc.GetClient(1, $client)

results in an unknown error (translated):

Exception during call of "GetClient" with 2 argument(s):  "Unknown Errror (Exception of  HRESULT: 0x80004005 (E_FAIL))"
Line:1 char:15
+ $dbc.GetClient <<<< (1, $client)
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation

Determining the method signature with Get-Member ($db | gm) shows

    TypeName: System.__ComObject#{4d47cc6a-763d-4a87-bbe1-96a96ccd79ae}

Name                 MemberType Definition
----                 ---------- ----------
Connect              Method     void Connect (string)
GetClient            Method     void GetClient (int, IClient)

Unfortunately $client is of type

TypeName: System.__ComObject#{103f5418-5cff-4ecb-adba-97bbfb04390c}

As far as I understand this problem, there is no wrapper class for the $client COM object. It should be possible to get this to work using .Net Reflection InvokeMember.

I tried

$a = @(1, $client)
[System.__ComObject].InvokeMember("GetClient", [System.Reflection.BindingFlags]::InvokeMethod, $null, $db, $a)

which results in an other strange error.

So, what can I do to make this work?

One helpful link was http://www.mcleod.co.uk/scotty/powershell/COMinterop.htm

EDIT:

Doing the same in Visual Basic works (so there must be a way for PowerShell too):

Set dbc = CreateObject("BMS.MOL.DBConnector")
Set client = CreateObject("BMS.MOL.Client")

dbc.GetClient 1, client
WScript.Echo client.Hostname

The IClient interface is defined like the following:

MIDL_INTERFACE("103F5418-5CFF-4ECB-ADBA-97BBFB04390C")
IClient : public IDispatch
{
public:
    ...
    virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_HostName( 
        /* [retval][out] */ BSTR *pVal) = 0;

};

and the IDBConnector looks like this:

MIDL_INTERFACE("4D47CC6A-763D-4A87-BBE1-96A96CCD79AE")
IDBConnector : public IDispatch
{
public:
    virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Connect( 
        BSTR bstrServer) = 0;

    virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetClient( 
        long nIndex,
        IClient *pIClient) = 0;
...
};