1

I am trying to communicate with a COM application using PowerShell. When I instantiate it, I can only talk to it through the IDispatch interface. That in itself is interesting, because I can early-bind to it in Visual Studio and talk to it 'directly'.

When I do:

$obj= New-Object -ComObject ComAssembly.Identifier # that's a made up name
$obj | gm

I get back only standard .Net stuff. But I can call properties using this syntax:

$path = [System.__ComObject].InvokeMember('Path',[System.Reflection.BindingFlags]::GetProperty,$null,$obj,$null)

That will give me the Path property.

What I want to do is call a method, which takes two parameters (in my case a string and the $path parameter). I found that the general way to call a method is this::

$anotherthing = [System.__ComObject].InvokeMember('SomeMethod',[System.Reflection.BindingFlags]::InvokeMethod,$null,$cmc,<args>)

My question: what is the syntax to supply <args>? I tried to simply pass them as arguments, that doesn't work.

Rno
  • 784
  • 1
  • 6
  • 16
  • I'd guess it should be an array. Did you check the [docs](https://learn.microsoft.com/en-us/dotnet/api/system.type.invokemember?view=netframework-4.8)? It actually says there `object[] args`, and "An array containing the arguments to pass to the member to invoke.". – CherryDT Apr 12 '20 at 00:59
  • For example: `$anotherthing = [System.__ComObject].InvokeMember('SomeMethod',[System.Reflection.BindingFlags]::InvokeMethod,$null,$cmc,new Object[] {'SomeString', $path})` – CherryDT Apr 12 '20 at 01:01
  • Actually, I think I was pointing you to the wrong place and with the wrong example insofar that it was more C# and less PowerShell even though both call a .NET function – CherryDT Apr 12 '20 at 01:05
  • 2
    Sorry about that. Try this syntax instead: `@('SomeString', $path)` – CherryDT Apr 12 '20 at 01:05
  • Tried that already with no luck – Rno Apr 12 '20 at 01:07
  • OK I probably should have paid more attention in the first place - sorry for the rushed wrong answer then. I should rather go to sleep ;) I hope someone else can help. – CherryDT Apr 12 '20 at 01:09
  • DW that was actually helpful! – Rno Apr 12 '20 at 01:11
  • I did the @(string, string) thingie forgetting that the string wasn't arbitrary (silly me) – Rno Apr 12 '20 at 01:18
  • It can vary depending on the method itself, do you have some real reproducing code? – Simon Mourier Apr 12 '20 at 06:39

1 Answers1

1

In this particular case, where SomeMethod simply takes two string arguments, wrapping them in an array as @CherryDT (thanks) suggested did the trick:

$obj= New-Object -ComObject ComAssembly.Identifier # that's a made up name
$path = [System.__ComObject].InvokeMember('Path',[System.Reflection.BindingFlags]::GetProperty,$null,$obj,$null)
$anotherthing = [System.__ComObject].InvokeMember('SomeMethod',[System.Reflection.BindingFlags]::InvokeMethod,$null,$obj,@('SomeString', $path))
Rno
  • 784
  • 1
  • 6
  • 16