Autor |
Beitrag |
richy
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 28.05.12 18:37
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
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 28.05.12 23:11
Ein laufendes COM Object kannst du dir per Marshal.GetActiveObject ranholen. Deine gewünschte Methode am Object aufrufen kannst du in dem du dir den Typ des Objects ranholst und am Typ dann die InvokeMember Methode benutzt. Wenn d VS2010 oder neuer einsetzt kannst du dir den Teil mit Typ ranholen und InvokeMember vereinfachen in dem du die Rückgabe von GetActiveObject als dynamic definierst.
|
|
richy 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 02.06.12 21:40
Was meinst du was du in deinem Python Code an die Dispatch übergibst?
|
|
richy 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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).
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"); } } } } |
Zuletzt bearbeitet von richy am So 10.06.12 18:39, insgesamt 1-mal bearbeitet
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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.
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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 |
Für diesen Beitrag haben gedankt: richy
|
|
richy 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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.
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
|
|