Windows Application Automation with python/COM

怎甘沉沦 提交于 2019-12-08 08:21:37

问题


I'm trying to automate ChemDraw for a user in the background, preferably avoiding using SendKeys() as I believe that requires a ChemDraw instance to be visible for that to work. What I need to do is somehow click Edit -> Copy As -> InChI programmatically, then retrieve the result from the Windows clipboard.

We're currently using Python and COM scripting to attempt this. Here's our current code:

    # Opens ChemDraw and loads the file, while keeping the window hidden.
    ChemDraw = w32.DispatchEx('ChemDraw.Application') # ChemDraw Application Object
    ChemDraw.Visible = False                          # Makes Invisible
    Compound= ChemDraw.Documents.Open(cdx_filepath)      # ChemDraw File Object (Can be seen with ChemDraw.Activate())

    # Selects the whole molecule.
    Compound.Objects.Select()

    # Here is where we need to figure out how to do CopyAs and Save off clipboard content.

    # Saves the file and Quits afterwards.
    Compound.SaveAs(jpg_filepath)
    ChemDraw.Quit()

I guess I have two questions: how do we access "Edit" in the toolbar and the resulting values in it? How do take the resulting object made from a line like "ChemDraw = w32.DispatchEx('ChemDraw.Application')" and determine what you can do with it? Part of the issue is that we can't seem to introspect the resulting DispatchEx object, thus we're having a hard answering our own question.


回答1:


The first question on how to access the contents of the "Edit" menu will be specific to ChemDraw itself, and not having that around, I am unable to give an immediate solution to that.

However, perhaps having an answer to the second question will allow you to answer the first one yourself, so, here goes: Assuming that the ChemDraw COM object allows it, you can use win32com.client.gencache.EnsureDispatch in place of DispatchEx in order to auto-generate Python classes for the object; this allows you to inspect the objects in greater detail. Rather than using EnsureDispatch, you can also access the underlying code-generating functionality directly, which may be more applicable to your workflow. See this question and this guide for further details.




回答2:


Because of the intricacies of COM scripting, I don't think you can really "access the edit menu", but there's a solution to access and store an InChI string:

For starters, I highly recommend you use comtypes over win32com because that gives a lot more information when you use dir(), and the syntax is almost identical as far as I can tell. Win32com gives little to nothing, so you're essentially looking for a needle in a dark room for mere functions (unless you have an SDK available). From there, you open the ChemDraw file, access the Objects class, then use the Data() method and input "chemical/x-inchi" (in your case). I've been working with ChemDraw for a project as well, and I had to do the same thing, so here's what you want:

import comtypes.client as w32
# Path for experimental ChemDraw File.
cdx_file = # Insert ChemDraw file path here

# Creates invisible ChemDraw object.
ChemDraw = w32.CreateObject("ChemDraw.Application")
ChemDraw.Visible = True

# Creates file object.
Compound = ChemDraw.Documents.Open(cdx_file)

# Converts file to InChI string.
file_inchi = Compound.Objects.Data("chemical/x-inchi")
print(file_inchi)

# Closes ChemDraw
ChemDraw.Quit()

P.S.: CreateObject is the comtypes equivalent of DispatchEx() for win32com.

Comtypes Documentation: https://pythonhosted.org/comtypes/

ChemDraw SDK: http://www.cambridgesoft.com/services/documentation/sdk/chemdraw/ActiveX11/ChemDrawControl10_P.html



来源:https://stackoverflow.com/questions/51502558/windows-application-automation-with-python-com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!