Entwickler-Ecke
Sonstiges (.NET) - Program über COM steuern
richy - Mo 28.05.12 18:37
Titel: Program über COM steuern
Hallo,
ich würde gerne mit C# über das Windows COM ein Program namens EventGhost fernsteuern. Unter Python ist dies mithilfe des Plugings win32com möglich, dann müsste es doch auch mit C# gehen. Wie kann ich das COM ansprechen und das Program und die Nachricht für das Program dem COM übergeben.
Pythoncode:
Quelltext
1: 2: 3:
| from win32com.client import Dispatch eg = Dispatch("EventGhost") eg.TriggerEvent(u"Der String mit dem Befehl.") //Es muss eigentlich an das Program nur ein String übergeben werden. |
Vielen Dank im Voraus.
Moderiert von
Th69: Code-Tags hinzugefügt
richy - Sa 02.06.12 21:26
Danke für die Antwort.
Ich habe nur das Problem das Program EventGhost heranzuholen. Word kann ich einfach per Word.Application holen. Wie kann ich die progid für das Program EventGhost herausfinden. Ich habe schon ausprobiert per Process.getProcesses() die EventGhost Processe zu bekommen und dann auf ihr Attribut Id zurückzugreifen. Jedoch nur eine Zahl bekommen und diese hat bei mir nicht als progid funktioniert.
Ralf Jansen - Sa 02.06.12 21:40
Was meinst du was du in deinem Python Code an die Dispatch übergibst?
richy - Fr 08.06.12 13:55
Du hast Recht "EventGhost" ist die allgemeine ProgID (mit OleComViewer überprüft). Aber das Programm muss jedesmal die Exception fangen, dass das Programm nicht greifbar ist (EventGhost ist geöffnet).
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Reflection; using System.Diagnostics; using System.Runtime.InteropServices.ComTypes;
namespace EventGhost { class Program { static void Main(string[] args) { doAction("EventGhost"); Console.ReadLine(); }
public static void doAction(String progID) { Type eg = null; Object eg2 = null;
try { eg = Type.GetTypeFromProgID(progID);
eg2 = Marshal.GetActiveObject(progID); } catch (Exception e) { Console.WriteLine("Can not open."); }
if (eg2 != null) { Console.Write("super"); } } } } |
Ralf Jansen - Fr 08.06.12 14:02
Zitat: |
Aber das Programm muss jedesmal die Exception fangen |
Die Exception hat sicherlich mehr Aussagekraft als 'Can not open'. Wenn du die dir die konkrete Exception ansiehst und nicht einfach mit einer generischen Meldung wegfrühstückst wirst du sicherlich einen Hinweis auf das Problem bekommen.
richy - Fr 08.06.12 14:21
Genauer ist die System.Runtime.InteropServices.COMException in mscorlib.dll aufgetreten. Es gab noch den Hinweis, dass MK_E_UNAVAILABLE ist.
Ralf Jansen - Fr 08.06.12 15:11
Das würde darauf hindeuten das EventGhost kein COM Automation Server ist und man sich gar nicht an eine laufende Instanz hängen kann. Bist du dir sicher das in php der Dispatch Aufruf sich an eine laufende Instanz hängt? Ich vermute dort wird einfach eine neue erzeugt.
richy - Sa 09.06.12 19:52
Der Dispatch Aufruf hat wirklich eine neue Instanz erzeugt. Jetzt habe ich dies nachgebildet, funktioniert super.
Mein Problem ist nun, dass InvokeMember nicht richtig funktioniert. Ich bekomme nur diese Fehlermeldung angezeigt:
Eine nicht behandelte Ausnahme des Typs "System.ArgumentException" ist in mscorlib.dll aufgetreten.
Zusätzliche Informationen: Für ein COM-Objekt muss die Eigenschaft "Set", "Get" oder ein Methodenaufruf angegeben werden.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Reflection; using System.Diagnostics; using System.Runtime.InteropServices.ComTypes;
namespace EventGhost2 { class Program { static void Main(string[] args) { doAction("EventGhost"); Console.ReadLine(); }
public static void doAction(String progID) { Type eg = null; object eg2 = null; eg = Type.GetTypeFromProgID(progID); eg2 = Activator.CreateInstance(eg); if (eg2 != null) { Console.WriteLine("Bis hier funktioniert es.");
eg.InvokeMember("TriggerEvent", BindingFlags.GetField, null, eg2, new String[1] {"Aktion für EventGhost"}); } } } } |
Moderiert von
Christian S.: Code- durch C#-Tags ersetzt
Ralf Jansen - Sa 09.06.12 20:02
BindingFlags.GetField? Ist TriggerEvent nicht eher eine Methode als ein Feld? Dann wären die BindingFlags eher
C#-Quelltext
1:
| BindingFlags.Public | BindingFlags.InvokeMethod |
richy - So 10.06.12 00:23
Vielen Dank Ralf Jansen. Jetzt läuft mein Programm.
Das C# Program mit dem man EventGhost fernsteuern kann. Ersetze den String "Aktion" mit dem Befehl, der getriggert werden soll.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Reflection; using System.Diagnostics; using System.Runtime.InteropServices.ComTypes;
namespace EventGhost { class Program { static void Main(string[] args) { doAction("EventGhost"); }
public static void doAction(String progID) { Type typeEventGhost = null; object EventGhost = null;
typeEventGhost = Type.GetTypeFromProgID(progID); EventGhost = Activator.CreateInstance(typeEventGhost);
if (EventGhost != null) { typeEventGhost.InvokeMember("TriggerEvent", BindingFlags.Public | BindingFlags.InvokeMethod, null, EventGhost, new String[1] {"Aktion"}); }
} } } |
Moderiert von
Christian S.: Code- durch C#-Tags ersetzt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!