从COM方法中检索会话ID

4
我有一个名为GoLogon的方法,它属于一个名为BS.Logon的COM对象,需要5个参数:
  • 用户名
  • 密码
  • 应用程序ID
  • XML根节点
  • IP地址
该方法使用用户名、密码和其他细节登录到Web服务器,并返回会话ID。
我已编写了Powershell脚本以调用GoLogon方法,如下所示。
$obj=New-Object -ComObject BS.Logon
$sessionid=$obj.GoLogon([ref]$bUsername,$bPassword,$appid,$xmlroot,[ref]$ipad)
Write-Host $sessionid

当脚本执行时,该方法能够成功登录。我可以在数据库中看到会话ID的详细信息,但是我无法通过脚本获取会话ID的详细信息。变量$sessionid返回空值。此外,脚本抛出异常。
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`

堆栈跟踪如下:

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      :

请告诉我如何从该方法中获取会话ID值。

你的问题很可能是在参数中使用了 [ref]。"[ref] 用于 COM 或 RPC 声明指针属性。在 .NET 中,[ref] 用于参数重定向。这两者完全不兼容。" - Jan Chrbolka
@Jan Chrbolka,我也尝试使用包装器,但是脚本抛出了另一个异常。你可以提供一下如何为我的脚本使用包装器吗?还有就是我忘了提及的是,这个方法返回一个指针值。 - Basavaraju B K
@Basavaraju B K,你应该给出Gologon方法的C++签名。 - JPBlanc
@JanChrbolka 感谢您的帮助。封装程序有效了。现在我能从这个方法中获取会话ID了。 - Basavaraju B K
@JPBlanc 谢谢你也。 - Basavaraju B K
显示剩余8条评论
1个回答

2
PowerShell似乎对定义为VARIANT的COM参数存在问题。
正如GoLogon的C++签名所示,这在这里是适用的。
STDMETHODIMP CLOG::GOLogon(VARIANT *pvEmailId, BSTR bsPassword, BSTR bsIPAddress, BSTR bsSoloBuildVer, VARIANT *pvXML, BSTR *bsSessionId)

这篇文章中提出的答案"Invalid callee" calling a com object是使用VariantWrapper。
在你的情况下,这应该解决问题。
#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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接