Seite 1 von 1

Problem mit Dispatch (pywin32)

Verfasst: Freitag 24. Februar 2012, 23:31
von nuts
Hallo zusammen,


ich versuche gerade mir Grundkenntnisse zu Python anzueigenen und bin gleich auf ein Problem gestossen.
Bin ziemlicher Anfänger in Python (und OOB) also habt etwas Nachsicht wenn ich mit den Begriffen teilweise daneben liege.

Aufgabestellung: Den DVBViewer (TV Software) über dessen COM-Interface steuern.
Soweit so gut. Das klappt auch schon mit diesem Skript:

Code: Alles auswählen

import pythoncom
import win32com.client
from win32com.client import Dispatch


import win32com.client

# Die Verbindung zum COM-Interface aufbauen
odvbviewer=Dispatch("DVBViewerServer.DVBViewer")
try:
# "Sendcommand" gehört DVBViewer Objekts - das stimmt soweit 
	odvbviewer.SendCommand(111)
except pythoncom.com_error:
	print "error"

Nun zu den Fragen:
1.
import win32com.client
from win32com.client import Dispatch
Wieso muss ich mir die Dispatch Funktion eigentlich noch explizit herzitieren obwohl das Modul win32com.client schon eingebunden ist?

edit\ Frage 1 hat sich erledigt.
Das explizit herzitieren ist nur nötig wenn man "Dispatch" direkt verwenden will?
Also alternativ: win32com.client.Dispatch

2.
Läuft der DVBViewer nicht bei der Skriptausführung wird er durch Dispatch("DVBViewerServer.DVBViewer") gestartet.
Das mag der DVBViewer gar nicht (crasht dann :lol: ).
Laut Doku zum DVBViewer COM-Interface:
The DVBViewer registers itself in the ROT when running. You normaly do a getactiveobject to connect to it.
Ich bräuchte also eine entsprechende Getobject Funktion in Python?

3.
Es gelingt mir nicht in den Pfad mit der Errorabfrage zu gelangen.
z.B.:

Code: Alles auswählen

import pythoncom
import win32com.client
from win32com.client import Dispatch

odvbviewer=Dispatch("DVBViewerServer.DVBViewer")
try:
	odvbviewer.SendCommand("Hallo")
except pythoncom.com_error:
	print "error"
Das kann nicht funktionieren, da Sendcommand einen Integer erwartet.
Nur wie kann ich darauf reagieren?

So das wars erstmal.

Gruß & Danke schonmal

Nuts




P.S. Um es deutlicher zu machen mal noch ein autoit Skript mit der gewünschten Funktionalität (bis auf Frage3).
$odvbviewer=ObjGet("", "DVBViewerServer.DVBViewer")
If @error Then
; z.B. wenn der DVBViewer nicht läuft
ConsoleWrite("error" & @crlf)
else
$odvbviewer.Sendcommand(111)
; die Funktion Sendcommand aufrufen
endif

Re: Problem mit Dispatch (pywin32)

Verfasst: Freitag 24. Februar 2012, 23:58
von BlackJack
Ad 1) Da Du `win32com.client` nirgens benutzt, kannst Du Dir den Import auch sparen. Insbesondere das doppelte importieren.

Ad 3) Da Du bei 2. sagst, das die Zeile vor dem ``try`` das Skript zum Absturz bringt, wird danach nichts ausgeführt. Nicht das `SendCommand()` und folgerichtig natürlich auch keine eventuelle Fehlerbehandlung.

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 00:14
von nuts
zu1) Die Dispatch Funktion ist doch Teil von win32com.client?
Diese Frage ist glaube ich aber geklärt (s. edit)

zu3)
Das Skript funktioniert mit laufendem DVBViewer einwandfrei.
Den Test mit der String ("hallo") anstatt Integer (111) Übergabe habe ich be laufendem DVBViewer ausgeführt.
In diesem Fall crasht mein Skript dann leider in der Zeile:
odvbviewer.SendCommand("hallo")

Leider ohne das erwartete Errorhandling.

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 01:14
von nuts
Ich konnte die Probleme fast lösen: 8)

Code: Alles auswählen

import pythoncom
import win32com.client
from win32com.client import GetObject

odvbviewer=None
try:
	odvbviewer=GetObject(Class="DVBViewerServer.DVBViewer")
except pythoncom.com_error:
	odvbviewer=None
	print "error"

if odvbviewer is not None:
	try:
		odvbviewer.SendCommand(111)
	except pythoncom.com_error:
		print "error"


print "exit"
Eines bleibt jedoch:
Wenn in der Zeile "odvbviewer.SendCommand(111)" Unsinn steht d.h. ungültige Wertübergabe wie z.B. "odvbviewer.SendCommand("hallo")"
crasht mein Skript.
Wieso lande ich dann nicht im Errorhandler? :?

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 01:44
von BlackJack
@nuts: Da ist immer noch ein unnötiges ``import win32com.client`` in dem Skript. Du benutzt ja nur `GetObject` und das wird in einer anderen Zeile separat importiert.

Die erste Ausnahmebehandlung ist umständlich und unschön. In der Ausnahmebehandlung bräuchtest Du `odvbviewer` nicht an `None` binden, denn das ist es ja bereits vor dem ``try`` schon, und wenn der ``except``-Zweig ausgeführt wurde, dann wurde auch der Name zwischendurch nicht an einen anderen Wert gebunden. Das binden an `None` und die spätere Prüfung sind aber äusserst unschön, weil Du damit einen speziellen Fehlerwert einführst, den man mit Ausnahmen ja gerade vermeiden will. Die wurden erfunden, damit man so etwas nicht mehr machen muss. Du könntest statt dessen die ``try``/``except``-Blöcke anders schachteln oder einen ``else``-Zweig verwenden.

Ich kenne mich mit COM nicht aus, aber es könnte durchaus sein, dass falsche Argumenttypen nicht erkannt werden können!? Ist zum Beispiel in der Regel bei `ctypes` so.

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 02:01
von nuts
Den win32com.client brauch ich später noch.

Nun ist es so, dass die übergebenen Werte (111 bzw. "Hallo") später mal aus einer Datei eingelesen werden und nicht festverdrahtet im Code stehen.
Das ermöglicht potentiellen Usereingriff. :mrgreen:
Irgendwie muss ich das abfangen. :?
Man könnte den Wert auch zuerst auf Integer prüfen und dann in die Sendcommand Funktion packen.
Vielleicht hat ja auch noch einer ne Idee wieso das mit dem Errorhandler nicht klappt?

Die unschöne Verschachtelung ist jetzt ein Überbleibsel aus dem fehlenden Errorhandling.
So genau hab ich da noch nicht drüber nachgedacht (fange mit Python ja auch gerade erst an).
Hast du mal ein Beispiel wie man das sauber schachtelt?

P.S. Danke schonmal für deine Antworten.

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 10:10
von BlackJack
@nuts: Den Spezial-Fehlerwert könnte man so vermeiden:

Code: Alles auswählen

# 
# Verschachtelt:
# 
try:
    # code A
    try:
        # code B
    except Error:
        # code C
except Error:
    # code D
# 
# oder mit ``else``:
# 
try:
    # code A
except Error:
    # code D
else:
    try:
        # code B
    except Error:
        # code C
Wobei man Ausnahmen sowieso nur behandeln sollte, wenn im ``except``-Teil etwas sinnvolles tun beziehungsweise tun kann. Einfach nur "error" ausgeben und weitermachen als sei nichts geschehen ist in der Regel nicht sinnvoll.

Re: Problem mit Dispatch (pywin32)

Verfasst: Samstag 25. Februar 2012, 10:29
von nuts
Okay verstanden. So werde ich das dann machen.
Für den zweiten Fehler werde ich auf Integer und den zugelassenen Wertebereich prüfen.

Das im Zweig des Errorhandling etwas sinnvolles passieren sollte ist mir klar.
Die eingefügten Codezeilen sind nur Ausschnitte zur Verdeutlichung (so kenne ich das aus anderen Foren zum Thema Programmieren).