4
votes

I have a method named GoLogon in a COM object named BS.Logon which requires 5 parameters:

  • Username
  • Password
  • ApplicationID
  • XMLRoot
  • IPAddress

This method logins to the web server with the username, password, and other details, and returns the session ID.

I have written the Powershell script to call the method GoLogon as below.

$obj=New-Object -ComObject BS.Logon
$sessionid=$obj.GoLogon([ref]$bUsername,$bPassword,$appid,$xmlroot,[ref]$ipad)
Write-Host $sessionid

When the script is executed, the method makes successful login. I can see the session ID details in the database, but I am not able to get the session ID details through script. The variable $sessionid returns null. Also the script throws exception as

Exception calling "GoLogon" with "5" argument(s): "Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))"
At E:\Logon.ps1:18 char:1
+ $obj.Login([ref]$bUsername,$bPassword,$appid,$xmlroot,[ref]$ipad)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation`

The stacktrace is:

Exception             : System.Management.Automation.MethodInvocationException: Exception calling "GoLogon" with "5" argument(s): "Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))" ---> System.Reflection.TargetInvocationException: 
Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))
--- End of inner exception stack trace ---
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Management.Automation.ComMethod.InvokeMethod(PSMethod method, Object[] arguments)
--- End of inner exception stack trace ---
at System.Management.Automation.ComMethod.InvokeMethod(PSMethod method, Object[] arguments)
at System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod method, PSMethodInvocationConstraints invocationConstraints, Object[] arguments)
at System.Dynamic.UpdateDelegates.UpdateAndExecute6[T0,T1,T2,T3,T4,T5,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
at System.Management.Automation.Interpreter.DynamicInstruction 7.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          : 
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : ComMethodTargetInvocation
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, E:\Logon.ps1: line 18
PipelineIterationInfo : {}
PSMessageDetails      :

Please suggest me how to get the session ID value from the method.

1
Your problem is most likely that you are using [ref] in your parameters. "[ref] is used by COM or RPC to declare pointer attributes. [ref] in .NET is used for parameter re-direction. These are in no way compatible."Jan Chrbolka
@Jan Chrbolka actually those two [ref] parameters which are arguments to method refers to pointers variables in COM.Basavaraju B K
This has always been a problem for me in PowerShell. Have a look here ...RE: "Invalid callee" calling a com object This describes how to use a Variant wrapper. It may work in your case. $variable = new-object object $wrapper = New-Object Runtime.InteropServices.VariantWrapper($variable) ## now call the method with the wrapped object $object.method([ref] $wrapper )Jan Chrbolka
@Jan Chrbolka Even I tried with the wrapper, but the script throws another exception. Can you please provide the wrapper usage for my script? Also forgot to mention, The method returns a pointer value.Basavaraju B K
Sorry, that was a long shot, as I'm definitely no expert at .COM. Do you have source code for the .COM object? Could you add that to the question? Or at least show definitions for the ByRef parameters? For the wrapper in your code, $wrapbUservame = New-Object Runtime.InteropServices.VariantWrapper($bUsername) $sessionid=$obj.GoLogon([ref]$wrapbUservame .... and the same for IPJan Chrbolka

1 Answers

2
votes

PowerShell seems to have a problem with COM parameters defined as VARIANT.

This is the case here, as the C++ signature of GoLogon suggests.

STDMETHODIMP CLOG::GOLogon(VARIANT *pvEmailId, BSTR bsPassword, BSTR bsIPAddress, BSTR bsSoloBuildVer, VARIANT *pvXML, BSTR *bsSessionId)

The answer suggested in this post "Invalid callee" calling a com object is to use a VariantWrapper.

In you case this should do the trick.

#define VariantWrapper for variables to be passesed as VARIANT
$wrapbUservame = New-Object Runtime.InteropServices.VariantWrapper($bUsername) 
$wrappvXML = New-Object Runtime.InteropServices.VariantWrapper($pvXML)

#pass a [ref]VariantWrapper to .COM method
$sessionid=$obj.GoLogon([ref]$wrapbUservame,$bPassword,$appid,[ref]$wrappvXML,$ipad)