microsoft.public.windows.powershell
[Top] [All Lists]

RE: "Invalid callee" calling a com object

Subject: RE: "Invalid callee" calling a com object
From: Bob Landau
Date: Wed, 30 Dec 2009 08:34:01 -0800
Newsgroups: microsoft.public.windows.powershell
Ok now I understand where you're coming from; OLETool is a great tool when 
you don't have the source for the component.

Powershell specifically I've found has problems with at least some OUT 
parameters. The most recent one I dealt with is [DateTime]::TryParse it 
should be called like this

[DateTime]::TryParse(<some date>, $date)

but must be called as 
$date = new-object DateTime
[DateTime]::TryParse(<some date>, [ref]$date)

I tried the same trick with your compoent but it unfortunatley has a 
VARIANT*.  I've found Powershell to have problems with these also 
specifically when these are out parameters.

Using the IDL signature you've given me I can easily reproduce the error 
you're seeing. Frankly I believe this to be a bug with Powershell's handling 
of "Variants*".  If you wish to bug this please do. I can send you the code 
to repro this. If you want me to I can but you'll not get credit :)

Here is a workaround (at least it works for me) but its much more combersome 
that it should be

$c = new-object -com "ProgID that implements the below interface"

## You MUST wrap an object into a VariantWrapper as shown here
$o = new-object object
$v = $v = New-Object Runtime.InteropServices.VariantWrapper($o)

## now call the method with the wrapped object
$c.ImportContent("Test", [ref] $v)


bob
"Garios" wrote:

> BTW:
> 
> I've found by using OLEView that the syntax is this:
> 
>  [id(0x0000000c), helpstring("method ImportContent")]
>         HRESULT ImportContent(
>                         [in] BSTR strArticleName, 
>                         [out] VARIANT* pArticleId, 
>                         [out, retval] long* pError);
> 
> 
> 
> 
> "Bob Landau" wrote:
> 
> > What language did you write this in? The signature doesn't look correct at 
> > all. With the exception of 2 or so special interfaces COM methods all 
> > return 
> > HRESULTS. 
> > 
> > Here is what it should look like in Powershell once you're components been 
> > instanciated
> > 
> > AToI Method     Variant AToI (string)
> > 
> > Here is the IDL syntax for the above 
> > id(1), helpstring("method AToI")] HRESULT AToI([in] BSTR strNum, 
> > [out,retval] VARIANT* Number);
> > 
> > Here is the implementation
> > STDMETHODIMP CNumber::AToI(BSTR strNum, VARIANT* Number)
> > {
> >     int retVal = _wtoi(strNum);
> >                 VariantInit(Number);
> >     Number->vt = VT_I4;
> >     Number->lVal = retVal;
> >     return S_OK;
> > }
> > 
> > I suggest that you start with something very simple such as this, get the 
> > protocol correct so that .NET and COM understand each other and then make 
> > your real component match.
> > 
> > 
> > "Garios" wrote:
> > 
> > > Thank you Bob,
> > > 
> > > Here is what I have:
> > > 
> > > Method     int ImportContent (string, Variant)
> > > 
> > > So this component is returning a Variant as a [retval]
> > > 
> > > I am using PS 32bit on a 32bit OS (W2008)
> > > 
> > > Get-Member returns all properties and methods for the object, this COM 
> > > object actually works on the same box when using with VBScript.
> > > 
> > > If I don't use [ref] then I get this error:
> > > Argument: '2' should be a System.Management.Automation.PSReference. Use 
> > > [ref].
> > > 
> > > If I use [ref]  then I get the error at the beginning of this post.
> > > 
> > > 
> > > "Bob Landau" wrote:
> > > 
> > > > You should not need to add  any attribute. ArticleId is a simple 
> > > > integer, 
> > > > there must be thousands if not more COM components that return integers 
> > > > as a 
> > > > [retval].
> > > > 
> > > > Post the IDL syntax for this specific method
> > > > Is this an inproc or exe coclass?
> > > > Is this a 32 or 64 bit OS?
> > > > Are you using 32 or 64 bit powershell host to instanciate this coclass?
> > > > Are you able to call any methods/properties on this coclass from 
> > > > powershell?
> > > > What does "$impObj | Get-Member" return?
> > > >    Do the members look correct?
> > > >    Search for the IID of the interface in the registry with RegEdit. 
> > > > Get-Member returns this as  
> > > >  
> > > >     TypeName: System.__ComObject#{<IID of the Interface that you have>}
> > > > 
> > > 

<Prev in Thread] Current Thread [Next in Thread>