OCX/COM:某些方法不会显示在 PowerShell 中

发布于 2024-10-22 04:38:15 字数 2637 浏览 4 评论 0原文

我有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

淡看悲欢离合 2024-10-29 04:38:15

查看此处项目中的 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...

颜漓半夏 2024-10-29 04:38:15

尝试使用 Get-Member 的 -force 参数?

顺便说一句,总猜测...

Try the -force parameter to Get-Member?

Total guess BTW...

笑叹一世浮沉 2024-10-29 04:38:15

尝试获取会员-静态吗?再猜一下。

Try Get-Member -Static? Guess again.

泛滥成性 2024-10-29 04:38:15

又是一次黑暗中的刺伤……

Get-Member -Force -View All

还要确保你获得了正确版本的对象。

Another stab in the dark...

Get-Member -Force -View All

Also make sure you are getting the right version of object.

节枝 2024-10-29 04:38:15

这种事情通常发生在没有类型库的情况下。当这种情况发生时,你通常会尝试这样的事情:

$bindingFlags = [System.Reflection.BindingFlags]::InvokeMethod
[System.__ComObject].InvokeMember('SetObject', $bindingFlags , $null, $setacl, 
                                  @("test", 1))

This kind of thing usually happens when there is no type library. When that happens you usually try something like this:

$bindingFlags = [System.Reflection.BindingFlags]::InvokeMethod
[System.__ComObject].InvokeMember('SetObject', $bindingFlags , $null, $setacl, 
                                  @("test", 1))
太阳哥哥 2024-10-29 04:38:15

这看起来像是 PowerShell 的特定限制。 博客中提到了两种解决方法

This looks like PowerShell specific limitation. There are two workarounds mentioned in the blog here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文