28

I'm trying to automate a process by using a COM object from Python (win32com), but I'm not getting the expected results... Is there a tool to explore/test COM objects without having to write a specific program? I mean, is there something that allows e.g. to instantiate a COM object and call its methods?

(Basically I'm trying to find out if my unexpected results are win32com's fault, and I'd like to avoid installing Visual Studio to write a C# app)

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Joril
  • 19,961
  • 13
  • 71
  • 88

4 Answers4

30

I actually wrote a replacement for the SDK tool OleView (afaik it doesn't support calling methods only enumerating) unimaginatively called OleViewDotNet. You can get the source code here or releases here.

What it does do is expose IDispatch methods (and some native interfaces) via a GUI so you can call them and it also provides an IronPython script window. You'd need to find your COM object by looking under "Registry -> CLSID By Name", find the entry (the filter can be used to select by name part) right click and select "Create Instance" that should show up a window similar to:

object information

then select the "Operations" menu at the bottom and choose "Open Dispatch" to get the method/property window.

enter image description here

There's a lot more you can do with this but that's a simple overview.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
tyranid
  • 13,028
  • 1
  • 32
  • 34
16

If you download the Windows SDK via the WebSetup you should be able to choose to just download the SDK tools. They include a program called Ole/COM Viewer (oleview.exe) that can be used to browse all registered COM objects, and for objects that support Ole Automation, open them and invoke methods.

FThompson
  • 28,352
  • 13
  • 60
  • 93
Chris Becke
  • 34,244
  • 12
  • 79
  • 148
  • 1
    I'm sorry, but I can't figure out if I'm using it correctly.. I've found the object I need, I click on "Create instance" and it gets selected (bold text).. What should I do now? There are a few interfaces available, but when I double-click on any of them I get "IDataObject interface viewer only supports IID_IDataObject" – Joril Oct 15 '10 at 14:08
  • 1
    Likely the package is missing iviewers.dll, which oleview.exe requires in the same directory. See: http://www.autoitscript.com/autoit3/docs/intro/ComRef.htm – bob-the-destroyer Oct 18 '10 at 21:48
  • Thanks for chiming in! Anyway the iviewers.dll is there, and if I move it elsewhere OLEviewer complains, so I'm guessing it's using it.. Anyway maybe I'm using it in a wrong way, what's the procedure to call a method using OLEviewer? I can't figure it out :/ – Joril Oct 20 '10 at 08:24
  • 2
    The problem is I suspect, that COM is a binary contract, so theres no general way to call into random interfaces. Well there is - it relies on the type information present when building 'dual' interfaces – Chris Becke Oct 20 '10 at 10:12
  • @Joril all you have to do is register iviewers.dll, think you need to run both versions of Regsvr32 (if you want 64 bit support too) – Peter Nimmo Jun 15 '17 at 11:09
12

I am exploring COM objects in PowerShell. Found this great recipe, provided by Jaap Brasser, which is easy to run and answered my question.

Get a list of all Com objects available Posted by Jaap Brasser on June 27, 2013

Note: This tip requires PowerShell 2.0 or above.

Recently a question was posted on the PowerShell.com forums: How to get a full list of available ComObjects? This tip will show how fetch all of them from the registry.

Here is the code that we can use to generate this list:

Get-ChildItem HKLM:\Software\Classes -ErrorAction SilentlyContinue | Where-Object {
   $_.PSChildName -match '^\w+\.\w+$' -and (Test-Path -Path "$($_.PSPath)\CLSID")
} | Select-Object -ExpandProperty PSChildName

The first Cmdlet reads out a complete list of values from HKLM:\Software\Classes and then verifies if the following two conditions are true:

  • Does the object match the naming convention for a ComObject?
  • Does the registry key have a CLSID folder? Every registered ComObject should have a CLSID as a unique identifier. An example of the output generated by this command is as follows:

    AccClientDocMgr.AccClientDocMgr
    AccDictionary.AccDictionary
    Access.ACCDAExtension
    Access.ACCDCFile
    Access.ACCDEFile
    Access.ACCDTFile
    Access.ACCFTFile
    Access.ADEFile

To make the process of discovering ComObject easier the following function can be used.

function Get-ComObject {

    param(
        [Parameter(Mandatory=$true,
        ParameterSetName='FilterByName')]
        [string]$Filter,

        [Parameter(Mandatory=$true,
        ParameterSetName='ListAllComObjects')]
        [switch]$ListAll
    )

    $ListofObjects = Get-ChildItem HKLM:\Software\Classes -ErrorAction SilentlyContinue | Where-Object {
        $_.PSChildName -match '^\w+\.\w+$' -and (Test-Path -Path "$($_.PSPath)\CLSID")
    } | Select-Object -ExpandProperty PSChildName

    if ($Filter) {
        $ListofObjects | Where-Object {$_ -like $Filter}
    } else {
        $ListofObjects
    }
}

This function is available in the TechNet Script Gallery:

http://gallery.technet.microsoft.com/Get-ComObject-Function-to-50a92047

bummi
  • 27,123
  • 14
  • 62
  • 101
Markus
  • 191
  • 1
  • 7
-3

For the record, I ended up writing a very small script using SciTe4AutoHotKey and AutoHotKey COM wrappers, no .Net required.
(and my unexpected results weren't Python's fault :) )

Joril
  • 19,961
  • 13
  • 71
  • 88
  • 1
    Both links are dead, here's working ones: First link: https://www.autohotkey.com/scite4ahk/ Second link: https://web.archive.org/web/20120305220421/https://www.autohotkey.com/wiki/index.php?title=COM_Wrappers – Shayan Jul 11 '22 at 13:31