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;
...
};