OCX/COM:某些方法不会显示在 PowerShell 中
我有 ActiveX 控件 SetACL.ocx。它已在我的系统上注册,我可以毫无问题地从 C# (Visual Studio 2010) 使用它。 Visual Studio 的对象浏览器显示所有方法。
然而,在 PowerShell 中,大约有三分之一的方法不会显示。如果我尝试调用缺少的方法之一,我会收到 MethodNotFound:
PS C:\> $setacl = New-Object -ComObject setacl.setaclctrl.1
PS C:\> $setacl | Get-Member
TypeName: System.__ComObject#{85869435-0ee3-440b-bf69-6c52c6638073}
Name MemberType Definition
---- ---------- ----------
AddACE Method int AddACE (string, bool, string, int, bool, int, int)
AddDomain Method int AddDomain (string, string, int, bool, bool)
AddTrustee Method int AddTrustee (string, string, bool, bool, int, bool, bool)
GetLastAPIError Method int GetLastAPIError ()
GetLastAPIErrorMessage Method string ()
GetLastListOutput Method string GetLastListOutput ()
GetResourceString Method string GetResourceString (int)
Reset Method void Reset ()
Run Method int Run ()
SetAction Method int SetAction (int)
SetListOptions Method int SetListOptions (int, int, bool, int)
SetLogFile Method int SetLogFile (string)
SetOwner Method int SetOwner (string, bool)
SetPrimaryGroup Method int SetPrimaryGroup (string, bool)
PS C:\> $setacl.SetObject("test", 1)
Method invocation failed because [System.__ComObject#{85869435-0ee3-440b-bf69-6c52c6638073}] doesn't contain a method named 'SetObject'.
At line:1 char:18
+ $setacl.SetObject <<<< ("test", 1)
+ CategoryInfo : InvalidOperation: (SetObject:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
有任何线索说明为什么 PowerShell 不显示所有可用方法但 Visual Studio 的对象浏览器却显示吗?
我尝试了 32 位和 64 位PowerShell 的版本。
更新 1:
这是 ODL 文件中缺少的方法之一的签名(是的,我有 OCX 的完整源代码,我是它的作者):
[id(2), helpstring ("Set the object on which all actions are to be performed")]
LONG SetObject(BSTR sObjectPath, LONG nObjectType);
更新 2:< /strong>
这是OCX 的源代码,可以直接在sourceforge上浏览。
更新3:
OCX可以从sourceforge下载。它包含在文件 SetACL 2.2.0.zip 中。
更新 4 - 可能的解决方案:
将 DISPIDS 1-7 的方法更改为更高的 DISPIDS,并引入 DISPIDS 1-7 的 7 个新的虚拟方法似乎可以解决问题。现在一切都显示在 PoSh 中 - 除了虚拟方法。
有人对此有解释吗?
I have the ActiveX control SetACL.ocx. It is registered on my system and I can use it from C# (Visual Studio 2010) without problems. Visual Studio's Object Browser displays all methods.
In PowerShell, however, about a third of the methods are not displayed. If I try to call one of the missing methods I get MethodNotFound:
PS C:\> $setacl = New-Object -ComObject setacl.setaclctrl.1
PS C:\> $setacl | Get-Member
TypeName: System.__ComObject#{85869435-0ee3-440b-bf69-6c52c6638073}
Name MemberType Definition
---- ---------- ----------
AddACE Method int AddACE (string, bool, string, int, bool, int, int)
AddDomain Method int AddDomain (string, string, int, bool, bool)
AddTrustee Method int AddTrustee (string, string, bool, bool, int, bool, bool)
GetLastAPIError Method int GetLastAPIError ()
GetLastAPIErrorMessage Method string ()
GetLastListOutput Method string GetLastListOutput ()
GetResourceString Method string GetResourceString (int)
Reset Method void Reset ()
Run Method int Run ()
SetAction Method int SetAction (int)
SetListOptions Method int SetListOptions (int, int, bool, int)
SetLogFile Method int SetLogFile (string)
SetOwner Method int SetOwner (string, bool)
SetPrimaryGroup Method int SetPrimaryGroup (string, bool)
PS C:\> $setacl.SetObject("test", 1)
Method invocation failed because [System.__ComObject#{85869435-0ee3-440b-bf69-6c52c6638073}] doesn't contain a method named 'SetObject'.
At line:1 char:18
+ $setacl.SetObject <<<< ("test", 1)
+ CategoryInfo : InvalidOperation: (SetObject:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Any clues as to why PowerShell does not show all available methods but Visual Studio's Object Browser does?
I tried both the 32- and 64-bit versions of PowerShell.
Update 1:
Here is the signature of one of the missing methods from the ODL file (yes, I have the full source code of the OCX, I am its author):
[id(2), helpstring ("Set the object on which all actions are to be performed")]
LONG SetObject(BSTR sObjectPath, LONG nObjectType);
Update 2:
Here is the source code of the OCX, directly browsable on sourceforge.
Update 3:
The OCX can be downloaded from sourceforge. It is included in the file SetACL 2.2.0.zip.
Update 4 - possible solution:
Changing the methods with the DISPIDs 1-7 to higher DISPIDS and introducing 7 new dummy methods with DISPIDS 1-7 seems to do the trick. Now everything shows up in PoSh - except the dummy methods.
Does anyone have an explanation for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
查看此处项目中的 IDL 文件,似乎 _DSetACL 的每个成员都与低于 8 的 DISPID 将被忽略。也许尝试以更高的索引启动 DISPID,例如 100?我确实记得一些“神奇”的dispid值,但我认为它们是极高的值,而不是低值,可能是错误的......
Looking at the IDL file from the project here, it appears that every member of your _DSetACL interface with DISPID below 8 is being ignored. Maybe try starting the DISPIDs at a higher index, like 100? I do recall some "magic" dispid values, but I thought they were extremely high values, not low values, could be wrong...
尝试使用 Get-Member 的 -force 参数?
顺便说一句,总猜测...
Try the -force parameter to Get-Member?
Total guess BTW...
尝试获取会员-静态吗?再猜一下。
Try Get-Member -Static? Guess again.
又是一次黑暗中的刺伤……
还要确保你获得了正确版本的对象。
Another stab in the dark...
Also make sure you are getting the right version of object.
这种事情通常发生在没有类型库的情况下。当这种情况发生时,你通常会尝试这样的事情:
This kind of thing usually happens when there is no type library. When that happens you usually try something like this:
这看起来像是 PowerShell 的特定限制。 博客中提到了两种解决方法 。
This looks like PowerShell specific limitation. There are two workarounds mentioned in the blog here.