Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Automatisierung von Windows-Anwendungen

PyCologne-Vortrag (Köln, 12.08.2009)

  • Login to see the comments

  • Be the first to like this

Automatisierung von Windows-Anwendungen

  1. 1. Automatisierung von Windows-Anwendungen Python for Windows PyCologne (12.08.2009, Köln) Andreas Schreiber <Andreas.Schreiber@dlr.de> http://andreas-schreiber.net | http://www.pycologne.de
  2. 2. Automatisierung von Windows-Anwendungen Um was geht es? <ul><li>Steuerung und Erweiterung existierender Windows-Applikationen </li></ul><ul><li>Applikationen mit COM-Interface </li></ul><ul><li>Client-Skripte in Python </li></ul><ul><li>Event-Handling </li></ul><ul><li>Add-Ins </li></ul><ul><li>Weitere Themen (hier nicht behandelt) </li></ul><ul><li>System-Programmierung unter Windows </li></ul><ul><li>Erstellung von Windows-Services mit Python </li></ul><ul><li>GUI-Programmierung </li></ul><ul><li>File-Management </li></ul>Modul win32com Module win32/*
  3. 3. COM Component Object Model <ul><li>Plattform-Technologie für Windows </li></ul><ul><li>Interprozesskommunikation </li></ul><ul><li>Dynamische Objekterzeugung </li></ul><ul><li>Client/Server-Architektur </li></ul><ul><li>COM-Client instanziert eine COM-Komponente in einem COM-Server und nutzt die Funktionalität des Objektes über COM-Interfaces </li></ul><ul><li>COM-Server ist eine DLL oder ein Executable </li></ul>
  4. 4. COM COM-Interface <ul><li>COM-Komponente kann dazu über allgemeine Schnittstellen und über spezielle Schnittstellen angesprochen werden. </li></ul><ul><li>Jedes Interface hat eine weltweit eindeutige Identifikationsnummer, die GUID (Globally Unique Identifier) </li></ul>// Standardschnittstelle aller COM-Komponenten [ object, uuid(00000000-0000-0000-C000-000000000046) ] interface IUnknown { [restricted] HRESULT _stdcall QueryInterface([in] GUID* rrid, [out] void** ppvObj); [restricted] unsigned long _stdcall AddRef(); [restricted] unsigned long _stdcall Release(); }
  5. 5. COM Automatisierung und Clients <ul><li>Automatisierung </li></ul><ul><li>Das Steuern von Anwendungen über COM-Interfaces wird als Automatisierung bezeichnet. </li></ul><ul><li>Clients </li></ul><ul><li>Im selben Prozess durch direkte Funktionsaufrufe </li></ul><ul><li>Auf derselben Maschine durch IPC calls </li></ul>Client Component Client Component COM Client Process Server Process
  6. 6. Pywin32 Python for Windows extensions <ul><li>Pywin32 </li></ul><ul><li>Python-Unterstützung für Windows </li></ul><ul><li>Entwickelt von Mark Hammond </li></ul><ul><li>http://sourceforge.net/projects/pywin32/ </li></ul><ul><li>win32com </li></ul><ul><li>Python COM Paket </li></ul><ul><li>Entwicklung von COM-Clients </li></ul><ul><li>Entwicklung vom COM-Servern </li></ul>
  7. 7. „ Hello World“ Microsoft Word from win32com import client word = client.Dispatch( &quot;Word.Application&quot; ) word.Visible = 1 doc = word.Documents.Add() doc.Content.Text = &quot;Hello World&quot;
  8. 8. Automatisierung von Applikationen <ul><li>Ermittlung der ProgID </li></ul><ul><li>Methoden der Applikation </li></ul>
  9. 9. Ermittlung der ProgID <ul><li>Notwendig zum Ansprechen (“Dispatch”) der Applikation </li></ul><ul><li>Mit Hilfe von WBEM </li></ul><ul><li>Schnell , aber unvollständig </li></ul><ul><li>Skript: getProgIDsFromWBEM.py http://onyame.pastebin.ca/1522189 </li></ul><ul><li>Ergebnis: progIDs_partialFromWBEM.txt </li></ul><ul><li>Über die Registry </li></ul><ul><li>Vollständig , aber sehr langsam </li></ul><ul><li>Skript: getProgIDsFromRegistry.py http://onyame.pastebin.ca/1522193 </li></ul><ul><li>Ergebnis: </li></ul>from win32com.client import Dispatch excel = Dispatch( „Excel.Application&quot; )
  10. 10. Beispiele für ProgIDs <ul><li>Access.Application </li></ul><ul><li>Citrix.ICAClient </li></ul><ul><li>Excel.Application </li></ul><ul><li>MSProject.Application </li></ul><ul><li>PowerPoint.Application </li></ul><ul><li>Visio.Application </li></ul><ul><li>Word.Application </li></ul>
  11. 11. Methoden der Applikation <ul><li>COM Dokumentation der Applikationen </li></ul><ul><li>Manchmal schwer zu finden </li></ul><ul><li>Generierung eines Python-Moduls mit makepy </li></ul><ul><li>/Python25/Lib/site-packages/win32com/client/makepy.py </li></ul><ul><li>Vorteile im Editor (Eingebeerweiterung) </li></ul><ul><li>Etwas schneller </li></ul><ul><li>Browsen der Schnittstellen mit combrowse </li></ul><ul><li>/Python25/Lib/site-packages/win32com/client/combrowse.py </li></ul>
  12. 12. Generierung eines Python-Moduls mit makepy <ul><li>Beispiel PowerPoint </li></ul><ul><li>91493440-5A91-11CF-8700-00AA0060263Bx0x2x8.py </li></ul>
  13. 13. Generierung eines Python-Moduls mit makepy Beispiel-Ausschnitt: PowerPoint  Slides  Add class Slides(DispatchBaseClass): CLSID = IID( '{91493469-5A91-11CF-8700-00AA0060263B}' ) coclass_clsid = None # Result is of type Slide def Add(self, Index=defaultNamedNotOptArg, Layout=defaultNamedNotOptArg): ret = self._oleobj_.InvokeTypes(2004, LCID, 1 , ( 13 , 0 ), (( 3 , 1 ), ( 3 , 1 )),Index , Layout) if ret is not None : # See if this IUnknown is really an IDispatch try : ret = ret.QueryInterface(pythoncom.IID_IDispatch) except pythoncom.error: return ret ret = Dispatch(ret, 'Add' , '{91493445-5A91-11CF-8700-00AA0060263B}' , UnicodeToString=0) return ret
  14. 14. Browsen der Schnittstellen mit combrowse
  15. 15. Browsen der Schnittstellen mit combrowse PowerPoint
  16. 16. Browsen der Schnittstellen mit combrowse Slides Add Slide Parameter
  17. 17. Alternativer Browser Type Library Browser tlbrowse.py
  18. 18. Beispiel from win32com import client ppt = client.Dispatch( „Powerpoint.Application&quot; ) ppt.Visible = 1 ppt.ActivePresentation.Slides.Add( 1 , 1 ) Index Layout
  19. 19. Debugging
  20. 20. Debugging Python Trace Collector <ul><li>import win32traceutil </li></ul>
  21. 21. Grundlegende Automatisierungen <ul><li>Skripte </li></ul><ul><li>Events </li></ul><ul><li>Add-Ins </li></ul>
  22. 22. Events <ul><li>Event-Abarbeitung </li></ul><ul><li>Event-Handler definieren </li></ul><ul><li>Applikation mit Event-Handler anfordern („Dispatch“) </li></ul><ul><li>Event-Schleife: Auf Events warten </li></ul><ul><li>Mögliche Events </li></ul><ul><li>Window-Eigenschaften („Resize“ etc.) </li></ul><ul><li>Document-Eigenschaften („Zellen-Inhalte“ etc.) </li></ul><ul><li>Buttons (z.B. in Toolbars) </li></ul>
  23. 23. Events Event-Handler definieren <ul><li>Beispiel Excel </li></ul><ul><li>Beispiel PowerPoint </li></ul>class EventManager(object): def OnSheetBeforeDoubleClick(self, sheet, target, cancel): print „Do something“ # something pass class EventManager(object): def OnSlideShowNextSlide(self, Wn): print „Do something“ # something pass
  24. 24. Events Welche Events gibt es? – Beispiel Excel <ul><li>Aus 00020813-0000-0000-C000-000000000046.py </li></ul>OnGetTypeInfo OnWorkbookAddinInstall OnSheetBeforeRightClick OnSheetFollowHyperlink OnWorkbookBeforePrint OnWorkbookBeforeXmlExport OnWorkbookDeactivate OnSheetSelectionChange OnInvoke OnSheetActivate OnWorkbookAddinUninstall OnAddRef OnQueryInterface OnWorkbookSync OnSheetChange OnGetTypeInfoCount OnWorkbookBeforeSave OnWorkbookAfterXmlExport OnWorkbookPivotTableCloseConnection OnSheetCalculate OnWorkbookPivotTableOpenConnection OnSheetBeforeDoubleClick OnSheetDeactivate OnWindowDeactivate OnRelease OnWindowResize OnSheetPivotTableUpdate OnWorkbookOpen OnWorkbookBeforeXmlImport OnWindowActivate OnNewWorkbook OnWorkbookNewSheet OnWorkbookAfterXmlImport OnWorkbookBeforeClose OnGetIDsOfNames
  25. 25. Events Welche Events gibt es? – Beispiel PowerPoint <ul><li>Aus 91493440-5A91-11CF-8700-00AA0060263B.py </li></ul>OnPresentationBeforeSave OnColorSchemeChanged OnSlideShowNextSlide OnSlideShowNextClick OnPresentationOpen OnPresentationSave OnWindowBeforeRightClick OnSlideShowBegin OnWindowBeforeDoubleClick OnWindowSelectionChange OnNewPresentation OnWindowDeactivate OnPresentationClose OnAfterPresentationOpen OnAfterNewPresentation OnSlideShowNextBuild OnPresentationNewSlide OnPresentationSync OnSlideSelectionChanged OnWindowActivate OnSlideShowEnd OnPresentationPrint
  26. 26. Events Applikation mit Event-Handler anfordern („Dispatch“) # Dispatch Excel with event handler from win32com.client import DispatchWithEvents excel = DispatchWithEvents( 'Excel.Application' , EventManager) excel.Visible = 1
  27. 27. Events Event-Schleife: Auf Events warten # Listen for events import threading, pythoncom stopEvent = threading.Event() while True : pythoncom.PumpWaitingMessages() # Necessary so that python doesn't hog CPU stopEvent.wait( .2 ) if stopEvent.isSet(): stopEvent.clear() break
  28. 28. Add-Ins <ul><li>Erstellen von Add-Ins </li></ul><ul><li>Ermitteln einer CLSID für das Add-In </li></ul><ul><li>Cut & Paste der Add-In Klassendefinition </li></ul><ul><li>Überschreiben von Methoden der Add-In Klasse </li></ul><ul><li>Registrieren des Add-Ins </li></ul>import pywintypes clsid = pywintypes.CreateGuid()
  29. 29. Add-Ins Klasse Addin class Addin(object): _com_interfaces_ = [ '_IDTExtensibility2' ] _public_methods_ = [] _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER _reg_clsid_ = '{2F1E606F-2A7B-46F9-AF6A-267C0036C348}' _reg_progid_ = 'Python.Test.Addin' _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy' def __init__( self ): import win32traceutil; self .application = None def OnConnection( self , application, connectMode, addin, custom): print 'OnConnection' , application, connectMode, addin, custom def OnDisconnection( self , mode, custom): print 'OnDisconnection ' ‚ mode, custom def OnAddInsUpdate( self , custom): print 'OnAddInsUpdate' , custom def OnStartupComplete( self , custom): print 'OnStartupComplete' , custom def OnBeginShutdown( self , custom): print 'OnBeginShutdown' , custom
  30. 30. Demos
  31. 31. Demo Twitter in PowerPoint <ul><li>Twitter message on every PowerPoint OnSlideShowNextSlide event </li></ul><ul><li>The speaker note will be the message, if existing </li></ul>python-twitter
  32. 32. Twitter in PowerPoint Implementation using Python’s win32com (1) <ul><li>Event handler for PowerPoint </li></ul>import twitter api = twitter.Api(username= 'python_demo' , password= '*' ) class EventManager(object): def OnSlideShowNextSlide(self, Wn): i = powerpoint.ActivePresentation. SlideShowWindow.View.Slide.SlideIndex for shape in powerpoint.ActivePresentation. Slides[i-1].NotesPage.Shapes: if shape.TextFrame.HasText: notes = shape.TextFrame.TextRange.Text api.PostUpdate(notes)
  33. 33. Twitter in PowerPoint Implementation using Python’s win32com (2) <ul><li>Dispatch PowerPoint with event handler and listen for events </li></ul>from win32com.client import DispatchWithEvents powerpoint = DispatchWithEvents( 'PowerPoint.Application' , EventManager) powerpoint.Visible = 1 # Listen for events import threading, pythoncom stopEvent = threading.Event() while True : pythoncom.PumpWaitingMessages() stopEvent.wait( .2 ) if stopEvent.isSet(): stopEvent.clear() break Source: Roy Han’s PyCon 2008 tutorial “Automating Windows Applications with win32com” http://tr.im/q43o
  34. 34. Quellen und Literatur
  35. 35. Quellen <ul><li>Tutorial Automating Windows Applications with win32com </li></ul><ul><li>Roy H. Han, Python Conference 2008, Chicago </li></ul><ul><li>http://us.pycon.org/2008/tutorials/AutomatingWindows/ </li></ul><ul><li>Website Python for Windows – Ressources and examples </li></ul><ul><li>Mustafa Görmezer </li></ul><ul><li>http://win32com.goermezer.de/ </li></ul>
  36. 36. Literatur Python Programming on Win32 <ul><li>Mark Hammond, Andy Robinson: Python Programming on Win32 </li></ul>

×