Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do Powershell query interface on a COM object

I created a COM object using Powershell:

$obj = new-object -com MyLib.MyObj

Then I need to query the interface "MyLib.MyInterface" on that object, but I have no idea how to do it with PowerShell.

In order word suppose I have the below C++ code

CComPtr<IInterface1> pInterface1;
CComPtr<IInterface2> pInterface2;
pInterface1->CoCreateInstance(CLSID_XXXX);   //in PowerShell: $obj = new-object -com MyLib.MyObj
pInterface1->QueryInterface(IID_YYYY, &pInterface2); //how to do this in PowerShell?

How do I do the same job with Powershell

Any comments?

Thanks

like image 977
Shuping Avatar asked Dec 07 '11 02:12

Shuping


People also ask

What is a COM object in PowerShell?

ComObject, or plain COM, increases the range of PowerShell activities. One way of looking at COM objects is as a mechanism for PowerShell to launch programs, for example, mimicking the RUN command. Another way of looking at ComObjects is performing the role previously undertaken by VBScript.

What is query interface?

Query interface is a type-safe way to achieve a safe downcasting and to allow interfaces to be aggregated to an object. Objects using the query interface must inherit from the Interface base class. An example of the use of query interface is shown below.


3 Answers

As an experiment I created $obj=new-object -com file. ("file" is the progid for the FileMoniker COM class). [Runtime.InteropServices.marshal]::GetIUnknownForObject($obj) gives me an System.IntPtr on my Windows 2008R2 machine. I was able to pass that value, along with the GUID for IMoniker to [Runtime.InteropServices.marshal]::QueryInterface and I got back the same value (ie same pointer) as I got from GetIUnknownForObject. So I was able to query the interface.

However, I'm not sure what good that does from Powershell. There are a lot of other methods in [Runtime.InteropServices.marshal] that might be of interest for dealing with COM from PS. But in general dealing with COM objects in PS is very different than dealing with them in C++.

EDIT I recently found and verified a way to access some COM components from PS that might be of interest here. The Windows SDK comes with a large set of IDL files. If you want to access one of these (and the component doesn't implement IDispatch), you can compile the IDL with MIDL and then use TLBIMP to create an interop assembly. I successfully did this with the 3 VSS Hardware Provider interfaces.

I also learned that you can use [type]::GetTypeFromCLSID to get a type from a CLSID. And depending on the component you can then instantiate it.

like image 168
Χpẘ Avatar answered Sep 19 '22 13:09

Χpẘ


If I understood your needs, try this:

$obj = new-object -com MyLib.MyObj

$type = $obj.gettype()

$type.GetInterfaces() # give a list of interfaces for the type

hope can be a starting point

like image 33
CB. Avatar answered Sep 20 '22 13:09

CB.


Here is an example where I call Word (see Word Object Model Overview) COM object :

# Create Word Object  
$wrd = new-object -com "word.application"

# Make Word Visible  
$wrd.visible = $true

# Open a document   
$doc = $wrd.documents.open("C:\silogix\silogix.doc")

To see properties and methods of your COM object you can use :

$obj | Get-Member
like image 28
JPBlanc Avatar answered Sep 19 '22 13:09

JPBlanc