What exactly does win32com.client.Dispatch("WScript.Shell")? - python

I was searching for a Python piece of code which would simulate keystrokes.
I stumble upon something using win32com.client.Dispatch("WScript.Shell").
I am not fan (at all) of Windows but it is to help a friend with automation of a game.
I got a problem, this works fine on notepad or firefox for example, it does write but not on his game.
In order to find wether it comes from his game or my automation I would like to have some details about win32com.client and what really represents WScript.Shell
Thank you all

Some citations:
As we discussed previously, automation objects are COM objects that
expose methods and properties using the IDispatch interface. So how do
we use these objects from Python? The win32com.client package contains
a number of modules to provide access to automation objects. This
package supports both late and early bindings, as we will discuss.
To use an IDispatch-based COM object, use the method
win32com.client.Dispatch(). This method takes as its first parameter
the ProgID or CLSID of the object you wish to create. If you read the
documentation for Microsoft Excel, you'll find the ProgID for Excel is
Excel.Application, so to create an object that interfaces to Excel,
use the following code:
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
(from this)
The WScript.Shell object provides functions to read system information
and environment variables, work with the registry and manage
shortcuts.
(from: 1 2)

Related

Is it possible to manipulate Visio drawings programmatically?

I'm developing an automatic documentation application in Python. One of the required features is to draw flowcharts. As the users use Visio, I would like to generate the flowcharts in Visio format, so the user can make fine adjustments in the drawing without having programming skills. I'm searching by VSTO Add-ins for Office, and while it looks possible to be used to make Visio drawings programmatically, it's not clear if it's possible to use it with my Python application. Would it be possible to use Python to send information to a VSTO Add-in and use it to draw a flowchart in Visio based on this information? How this can be implemented? Is there any other recommendation of how to generate a flowchart programmatically in a format that users can edit using a vector graphics editor?
There is no need to communicate with a VSTO based add-in. You can automate any MS Office application (including Visio) from a Python script. I believe pywin32 can help with such tasks.
from win32com.client import constants
appVisio = win32com.client.Dispatch("Visio.Application")
appVisio.Visible =1
doc = appVisio.Documents.Add("Basic Diagram.vst")
pagObj = doc.Pages.Item(1)
doc.SaveAs(r'e:\temp\MyDrawing.vsd')
doc.Close()
win32com gives you back a thin Python wrapper around a COM server provided by the application. The documentation for the Visio object model is here.
Be aware that the objects you get back are COM objects in a thin Python wrapper and so don't always behave like Python objects, and the documentation assumes you are writing in VBA not Python.

How to get code-completion for COM programming in PyCharm?

When using app = win32com.client.Dispatch('Some.Application'), is there any feasible way get code-completion in PyCharm? It is rather tedious having to retype (or copy-paste) everything from an API documentation, so would creating skeletons be. Is there no other way to let PyCharm know about the Interface provided via COM, especially if I can provide a .tlb file? Or is there at least some way automatically generate such a skeleton (or a wrapping module?) from the TypeLib?
Since there is no way for PyCharm to know the runtime type of app, you shouldn't expect to get code completion on app directly; at least not until they decide to add built-in support for generating code from type libraries.
However, you can exploit the fact that win32com implicitly generates code based on the type library as described in the first part of this answer, together with PyCharm's support for type hinting, to get code completion on COM methods.
Make sure that the Python types have been generated; their location is determined by the GUID of the COM object. For example, the types for Microsoft Word 2016 on my machine are available in
C:\Users\username\appdata\local\temp\gen_py\3.6\00020905-0000-0000-c000-000000000046x0x8x7\.
Add this folder to the path of your PyCharm Python interpreter; see e.g. this answer.
Import the modules for which you want code completion.
In the screenshots below, we use this approach with Word's Find:
Now, besides feeling dirty, this approach relies on the relevant types having been generated and the code completion is limited to the methods published by the object, so I imagine its usefulness in practice might be somewhat limited; in particular, anybody working on the code will have to generate the code, or the annotations will cause NameErrors. Personally, I would probably prefer using Jupyter for the exploratory part of the implementation process, and with minimal tweaks outlined in the answer mentioned above, Jupyter can be extended to have full code completion with win32com.

iTunes 11 scripting on Windows

Does anyone know of a way to programmatically inspect podcasts and create playlists via Python for iTunes 11 on Windows?
Prior to iTunes 11, one could script it on Windows from Python using the win32com.client package. While technically this is still possible, significant portions of the API have been removed with iTunes 11. Apple has also removed the iTunes COM SDK documentation from its website, and the win32com.client interface has always relied on lazy method lookup (so it's not possible to inspect the wrapped COM object for a list of methods or their expected arguments).
The best solution I've found is to use example scripts found on the web to guess at the API and use iPython to verify assumptions. It appears as though Boolean attributes like Podcast become non-existent when false.
For iTunes 10, one can write
is_podcast = track.Podcast
but in iTunes 11, one needs to write
is_podcast = getattr(track, 'Podcast', False)
To be able to resync any created playlists, one can restore the old sidebar, go to the device, go to the podcasts tab, and check off the playlists to sync (as with iTunes 10).

What would be the best way to use python's functions from excel?

Somebody really needs to fix this "subjective questions evaluator"
I usually compile my functions in a DLL and call them from excel. That works fine (well, let's just say it works)
Unfortunatelly, python cannot be compiled. I know of py2exe but I don't know that it can make a DLL.
So, ..., is there any other way ? I appreciate all ideas and suggestions on the matter.
One way is to write a COM server in Python, and call that from Excel. There are tutorials describing Win32 COM servers, and screencasts on calling such servers from Excel.
This is probably not a possible solution for you, but there is the Resolver One spreadsheet application (which is like Excel combined with Python). It is not connected with Excel in any way, but claims to be compatible to some extent.
Im surprised nobody mentioned pyxll. From the website:
PyXLL is an Excel addin that enables functions written in Python to be
called in Excel. Python functions can either be exposed as Excel user
defined functions that can be called from worksheets, as custom menu
items, or as macros.
There is an Excel Addin that allows you to do this called Discovery Script at xefion.com.
It's free but not open source. It's also based on the IronPython implementation.
I don't know any py2dll similar to py2exe.
However, you could create a dll in C and use the Very High Level Layer to call your script. I don't know it is an acceptable solution for you. Just an idea.
I had to do this some years back. My solution was to run small Python server that exported the functions using SOAP, then call the functions using Visual Basic's SOAP library. The advantage is that you don't have to ship a Python environment with your spreadsheets. The disadvantage is that the clients will need a network connection.

Is there a better way (besides COM) to remote-control Excel?

I'm working on a regression-testing tool that will validate a very large number of Excel spreadsheets. At the moment I control them via COM from a Python script using the latest version of the pywin32 product. Unfortunately COM seems to have a number of annoying drawbacks:
For example, the slightest upset seems to be able to break the connection to the COM-Server, once severed there seems to be no safe way to re-connect to the Excel application. There's absolutely no safety built into the COM Application object.
The Excel COM interface will not allow me to safely remote-control two seperate instances of the Excel application operating on the same workbook file, even if they are read-only.
Also when something does go wrong I seldom get any useful error-messages... at best I can except a numerical error-code or a barely useful message such as "An Exception has occurred". It's almost impossible to know why something went wrong.
Finally, COM lacks the ability to control some of the most fundamental aspects of Excel? For example there's no way to do a guaranteed close of just the Excel process that a COM client is connected to. You cannot even use COM to find Excel's PID.
So what if I were to completely abandon COM? Is there an alternative way to control Excel?
All I want to do is run macros, open and close workbooks and read and write cell-ranges? Perhaps some .NET experts know a trick or two which have not yet bubbled into the Python community? What about you office-hackers? Could there be a better way to get at Excel's innards than COM?
There is no way that completely bypasses COM. You can use VSTO (Visual Studio Tools for Office), which has nice .NET wrappers on the COM objects, but it is still COM underneath.
The Excel COM interface will not allow me to safely remote-control two seperate instances of the Excel application operating on the same workbook file, even if they are read-only.
This is not a limitation of COM, this is a limitation of Excel. Excel will not even let you open two files with the same name at the same time if they exist in different directories. It is a fundamental limitation of the Excel program.
To answer your other questions
If you check your python documentation, there should be a way to connect to an existing server if the connection is lost.
The lack of useful error messages again may be to do with Python.
You cannot even use COM to find Excel's PID.
COM is an internal object model and exposed what it wishes. PID are available to outside processes as much as they are to internal, there is no real reason to expose as a COM interface.
It is also possible to run Excel as a server application and use it as a calculation engine. This allows non IT users to specify business rules within Excel and call them through webservices. I have not worked with this myself, but I know a coworker of mine used this once. Walkthrough: Developing a Custom Application Using Excel Web Services could be a good starting point. A first glance at that page looks like it requires Sharepoint. This might not be suiteable for every environment.
Have you looked at the xlrd and xlwt packages? I'm not in need of them any more, but I had good success with xlrd on my last project. Last I knew, they couldn't process macros, but could do basic reading and writing of spreadsheets. Also, they're platform independent (the program I wrote was targetted to run on Linux)!
You could use Jython with the JExcelApi (http://jexcelapi.sourceforge.net/) to control your Excel application. I've been considering implementing this solution with one of my PyQt projects, but haven't gotten around to trying it yet. I have effectively used the JExcelApi in Java applications before, but have not used Jython (though I know you can import Java classes).
NOTE: the JExcelApi may be COM under the hood (I'm not sure).

Categories