- Überblick
- UI-Automatisierung (UI Automation)
- Mit UI-Automatisierung automatisierte Anwendungen und Technologien
- Projektkompatibilität
- UI-ANA-016 – URL zum Öffnen eines Browsers abrufen
- UI-ANA-017 – ContinueOnError True
- UI-ANA-018 – OCR-/Bildaktivitäten auflisten
- UI-DBP-006 – Containernutzung
- UI-DBP-013 – Falscher Gebrauch von Excel-Automatisierung
- UI-DBP-030 – Verwendung unzulässiger Variablen in Selektoren
- UI-PRR-001 – Klick simulieren
- UI-PRR-002 – Typ simulieren
- UI-PRR-003 – Offener Anwendungsmissbrauch
- UI-PRR-004 – Hartcodierte Verzögerungen
- UI-REL-001 – Große IDX in Selektoren
- UI-SEC-004 – Selektor-E-Mail-Daten
- UI-SEC-010 – App-/URL-Einschränkungen
- UI-USG-011 – Nicht zulässige Attribute
- UX-SEC-010 – App-/URL-Einschränkungen
- UX-DBP-029 – Unsichere Kennwortnutzung
- UI-PST-001 – Prüfungsprotokollebene in Projekteinstellungen
- UiPath-Browsermigrationstool
- Clippingbereich
- Computer Vision Recorder
- Aktivieren (Activate)
- Ankerbasis (Anchor Base)
- Browser anhängen (Attach Browser)
- Fenster anhängen (Attach Window)
- Benutzeingabe blockieren (Block User Input)
- Textfeld (Callout)
- Prüfen (Check)
- Klicken (Click)
- Bild anklicken (Click Image)
- Bild-Trigger anklicken (Click Image Trigger)
- OCR-Text anklicken (Click OCR Text)
- Text anklicken (Click Text)
- Trigger anklicken (Click Trigger)
- Anwendung schließen (Close Application)
- Registerkarte schließen (Close Tab)
- Fenster schließen (Close Window)
- Kontextbewusster Anker
- Ausgewählten Text kopieren (Copy Selected Text)
- Element Attribute Change Trigger
- Element vorhanden (Element Exists)
- Elementumfang (Element Scope)
- Element State Change Trigger
- Export UI Tree
- Strukturierte Daten extrahieren (Extract Structured Data)
- Untergeordnete Elemente finden (Find Children)
- Element finden (Find Element)
- Bild finden (Find Image)
- Bildübereinstimmung finden (Find Image Matches)
- OCR-Textposition finden (Find OCR Text Position)
- Relatives Element finden (Find Relative Element)
- Textposition finden (Find Text Position)
- Aktives Fenster abrufen (Get Active Window)
- Vorgänger-Element erhalten (Get Ancestor)
- Attribut erhalten (Get Attribute)
- Ereignisinfo erhalten (Get Event Info)
- Aus Zwischenablage erhalten (Get From Clipboard)
- Volltext erhalten (Get Full Text)
- OCR-Text erhalten (Get OCR Text)
- Passwort erhalten (Get Password)
- Position erhalten (Get Position)
- Quellelement erhalten (Get Source Element)
- Text erhalten (Get Text)
- Sichtbaren Text erhalten (Get Visible Text)
- Zurück (Go Back)
- Weiter (Go Forward)
- Zur Startseite (Go Home)
- Google Cloud Vision OCR
- Fenster ausblenden (Hide Window)
- Markieren (Highlight)
- Hotkey-Trigger (Hotkey Trigger)
- Darauf zeigen (Hover)
- Auf Bild zeigen (Hover Image)
- Auf OCR-Text zeigen (Hover OCR Text)
- Text beim Darauf zeigen (Hover Text)
- Bild vorhanden (Image Exists)
- Auf Bildschirm anzeigen (Indicate On Screen)
- .NET-Code einfügen
- Inject Js Script
- ActiveX-Methode aufrufen
- Tastendruck-Trigger (Key Press Trigger)
- Bild laden (Load Image)
- Fenster maximieren (Maximize Window)
- Microsoft Azure ComputerVision OCR
- Microsoft OCR
- Microsoft Project Oxford Online OCR
- Fenster minimieren (Minimize Window)
- Ereignisse überwachen (Monitor Events)
- Maus-Trigger (Mouse Trigger)
- Fenster verschieben (Move Window)
- Navigieren zu (Navigate To)
- OCR-Text vorhanden (OCR Text Exists)
- Auf Element erscheinen (On Element Appear)
- Auf Element verschwinden (On Element Vanish)
- Auf Bild erscheinen (On Image Appear)
- Auf Bild verschwinden (On Image Vanish)
- Anwendung öffnen (Open Application)
- Browser öffnen (Open Browser)
- Browser aktualisieren (Refresh Browser)
- Benutzerereignis wiedergeben (Replay User Event)
- Fenster wiederherstellen (Restore Window)
- Bild speichern (Save Image)
- Objekt auswählen (Select Item)
- Mehrere Objekte auswählen (Select Multiple Items)
- Hotkey senden (Send Hotkey)
- Ausschneidebereich einstellen (Set Clipping Region)
- Fokus legen auf (Set Focus)
- Text einstellen (Set Text)
- Auf Zwischenablage setzen (Set To Clipboard)
- Web-Attribut setzen (Set Web Attribute)
- Fenster anzeigen (Show Window)
- Prozess starten (Start Process)
- System-Trigger (System Trigger)
- Screenshot anfertigen (Take Screenshot)
- Tesseract OCR
- Text vorhanden (Text Exists)
- Tooltip
- Eingeben in (Type Into)
- Sicheren Text eingeben (Type Secure Text)
- Vordergrund verwenden
- Attribut abwarten (Wait Attribute)
- Warten, bis Element verschwindet (Wait Element Vanish)
- Warten, bis Bild verschwindet (Wait Image Vanish)
- Application event trigger
- Check/Uncheck
- Check App State
- Check Element
- Klicken (Click)
- Click Event Trigger
- Ziehen und Ablegen
- Extract Table Data
- For Each UI Element
- Attribut erhalten (Get Attribute)
- Get Browser Data
- Text erhalten (Get Text)
- Get URL
- Zu URL wechseln
- Markieren (Highlight)
- Darauf zeigen (Hover)
- Inject Js Script
- Tastenkombinationen
- Keypress Event Trigger
- Mouse Scroll
- Navigate Browser
- Objekt auswählen (Select Item)
- Set Browser Data
- Set Runtime Browser
- Text einstellen (Set Text)
- Screenshot anfertigen (Take Screenshot)
- Eingeben in (Type Into)
- Use Application/Browser
- Anhängen
- Prüfen (Check)
- Klicken (Click)
- Ziehen und Ablegen
- Daten extrahieren
- Attribut erhalten (Get Attribute)
- GetChildren
- GetRuntimeTarget
- GetText
- Get URL
- GoToUrl
- Markieren (Highlight)
- Darauf zeigen (Hover)
- IsEnabled
- Tastaturkürzel (Keyboard Shortcut)
- Mouse Scroll
- Offen
- Objekt auswählen (Select Item)
- Screenshot anfertigen (Take Screenshot)
- Eingeben in (Type Into)
- Wartestatus
- Führen Sie eine Browsersuche durch und rufen Sie Ergebnisse mithilfe von UIAutomation-APIs ab
- Web-Browsing
- Finden von Bildern
- Klicken auf Bilder
- Auslösen und Überwachen von Ereignissen
- Erstellen und Überschreiben von Dateien
- HTML-Seiten: Extrahieren und Bearbeiten von Informationen
- Bearbeiten von Fenstern
- Automatisierte Listenauswahl
- Finden und Bearbeiten von Fensterelementen
- Verwalten der Textautomatisierung
- Laden und Verarbeiten von Bildern
- Verwalten von mausaktivierten Aktionen
- Automatisieren der Anwendungslaufzeit
- Automatisierte Ausführung einer lokalen Anwendung
- Browsernavigation
- Web-Automatisierung
- Beispiel für Trigger Scope
- Aktivieren der Unterstützung für die UI-Automatisierung in DevExpress
- Computer Vision Local Server
- Mobile Automation
- Versionshinweise
- Projektkompatibilität
- Get Log Types
- Get Logs
- Get Page Source
- Get Device Orientation
- Get Session Identifier
- Install App
- Manage Current App
- Manage Other App
- DeepLink öffnen
- Open URL
- Mobile Device Connection
- Richtungswechsel
- Muster zeichnen
- Positional Swipe
- Press Hardware Button
- Set Device Orientation
- Screenshot anfertigen (Take Screenshot)
- Take Screenshot Part
- Element vorhanden (Element Exists)
- Execute Command
- Attribut erhalten (Get Attribute)
- Get Selected Item
- Text erhalten (Get Text)
- Set Selected Item
- Text einstellen (Set Text)
- Wischen
- Tap
- Type Text
- Terminal
- Versionshinweise
- Über das Terminal-Aktivitätspaket
- Projektkompatibilität
- Best Practices
- Find Text
- Get Color At Position
- Get Cursor Position
- Feld erhalten (Get Field)
- Feld an Position erhalten (Get Field at Position)
- Bildschirmbereich erhalten (Get Screen Area)
- Text erhalten (Get Text)
- Text an Position erhalten (Get Text at Position)
- Cursor bewegen (Move Cursor)
- Move Cursor to Text
- Strg-Taste senden (Send Control Key)
- Tasten senden (Send Keys)
- Sichere Tasten senden (Send Keys Secure)
- Feld setzen (Set Field)
- Feld an Position setzen (Set Field at Position)
- Terminalsitzung (Terminal Session)
- Warte auf Feldtext (Wait Field Text)
- Warte auf Bildschirmtext (Wait Screen Text)
- Warte auf Text an Position (Wait Text at Position)
UIAutomation-Aktivitäten
.NET-Code einfügen
UiPath.Core.Activities.InjectDotNetCode
Fügt .NET-Code in den Haupt-UI-Thread der Zielanwendung ein. Vorgesehen für die Verwendung mit .NET-UI-Anwendungen, die keine herkömmlichen Automatisierungstechnologien verfügbar machen oder mit herkömmlichen Mitteln nicht korrekt angezielt werden können.
Allgemein
-
BeiFehlerFortfahren (ContinueOnError) - Gibt an, ob die Automatisierung auch bei Auftreten eines Fehlers weiterlaufen soll. Das Feld unterstützt nur Boolesche Werte (Wahr, Falsch). Der Standardwert ist Falsch. Dadurch wird die Ausführung des Projekts beim Auftreten eines Fehlers angehalten, wenn das Feld leer. Wenn der Wert auf Wahr gesetzt ist, wird das Projekt weiter ausgeführt, auch wenn Fehler auftreten.
Hinweis: Wenn diese Aktivität in Try Catch enthalten ist und der Wert der Eigenschaft BeiFehlerFortsetzen auf „True“ gesetzt ist, wird kein Fehler beim Ausführen des Projekts aufgefangen. - AnzeigeName (DisplayName) - Der Anzeigename der Aktivität.
Eingabe
- Assembly – Der vollständige Pfad zur kompilierten .NET-Assembly, die Sie einfügen möchten. Dieses Feld unterstützt nur Strings und
String
-Variablen. -
Methodenname - Der Name der Methode, die Sie ausführen möchten. Nur öffentliche statische Methoden werden unterstützt.
Hinweis: Ein Typ kann nicht mehrere Methoden mit demselben Namen enthalten. In diesem Fall wird zur Laufzeit ein Fehler ausgegeben. - Target.ClippingRegion - Definiert das Ausschneide-Rechteck in Pixel im Verhältnis zum UIElement in folgenden Richtungen: links, oben, rechts, unten. Es unterstützt sowohl positive als auch negative Zahlen.
- Ziel.Element (Target.Element) - Verwendet die Variable UIElement, die von einer anderen Aktivität zurückgegeben wird. Die Eigenschaft kann nicht zusammen mit der Auswahleigenschaft verwendet werden. Dieses Feld unterstützt nur Variablen vom Typ UIElement.
- Ziel.Selektor (Target.Selector) - Texteigenschaft zum Suchen eines bestimmten UI-Elements, wenn die Aktivität ausgeführt wird. Die Eigenschaft ist genau genommen ein XML-Fragment, das Attribute des gesuchten GUI-Elements und einige übergeordnete Elemente spezifiziert.
- Target.TimeoutMS – Gibt die Zeit (in Millisekunden) an, die auf die Ausführung der Aktivität gewartet werden soll, bevor der Fehler
SelectorNotFoundException
ausgegeben wird. Der Standardwert ist 30000 Millisekunden (30 Sekunden). -
Ziel.WartenBisBereit (Target.WaitForReady) - Vor Ausführung der Aktionen warten, bis das Ziel bereit ist. Folgende Optionen sind verfügbar:
- Keine (None) - Wartet ausschließlich auf das UI-Zielelement, bevor die Aktion ausgeführt wird. Sie können diese Option beispielsweise verwenden, wenn Sie nur Text einer Website abrufen oder eine bestimmte Schaltfläche anklicken möchten, ohne auf das Laden aller UI-Elemente warten zu müssen. Beachten Sie, dass dies ungewünschte Folgen haben kann, wenn die Schaltfläche von Elementen wie Skripten abhängt, die noch nicht geladen sind.
-
Interaktiv/Abgeschlossen – Wartet, bis alle UI-Elemente in der Ziel-App vorhanden sind, bevor die Aktion tatsächlich ausgeführt wird.
Um zu beurteilen, ob sich eine Anwendung im Status „Interaktiv“ oder „Abgeschlossen“ befindet, werden die folgenden Tags überprüft:
- Desktop-Anwendungen (Desktop applications) - Eine Nachricht
wm_null
wird versendet, um zu prüfen, ob die Tags<wnd>
,<ctrl>
,<java>
oder<uia>
vorhanden sind. Sind die Tags vorhanden, wird die Aktivität ausgeführt. - Webanwendung
- Internet Explorer – Das
<webctrl>
-Tag wird verwendet, um zu überprüfen, ob der Status Bereit des HTML-Dokuments Abgeschlossen ist. Darüber hinaus muss der Status Beschäftigt auf „False“ festgelegt werden. - Andere – Das
<webctrl>
-Tag wird verwendet, um zu überprüfen, ob der Bereitschafts-Status des HTML-Dokuments Abgeschlossen ist.
- SAP-Anwendungen (SAP applications) - Zuerst wird geprüft, ob der Tag
<wnd>
vorhanden ist. Anschließend wird eine SAP-spezifische API verwendet, um zu prüfen, ob die Session verfügbar ist.
- Typname - Der Name der öffentlichen Klasse, die die ausführende Methode enthält. Dieses Feld unterstützt nur Strings und
String
-Variablen.
Sonstiges
- Privat (Private) - Bei Auswahl werden die Werte von Variablen und Argumenten nicht mehr auf der Stufe Verbose protokolliert.
Ausgabe
- Ergebnis – Das Ergebnis der aufgerufenen Methode, das in einer
Object
-Variablen gespeichert wird. Dieses Feld unterstützt nurObject
-Variablen.
Die Aktivität Inject .NET Code injiziert Code nur in die Standard-AppDomain.
Einige Anwendungen sind so strukturiert, dass sich die Elemente, auf die Sie möglicherweise zugreifen oder die Sie bearbeiten müssen, nicht innerhalb der Standard-AppDomain befinden. Daher reicht das Einfügen von Code in die Standard-AppDomain nicht aus. Wenn sich die UI-Elemente, die Sie anzeigen möchten, also in einer anderen AppDomain befinden, sind sie für den eingefügten Code nicht verfügbar.
Um dies zu beheben, müssen Sie den Injektionsprozess so ändern, dass er auf die genaue AppDomain abzielt, die die UI-Elemente enthält. Genauer gesagt müssen Sie Code aus der Funktion, die in der Standard-AppDomain ausgeführt wird, entweder in alle nicht standardmäßigen AppDomains oder in die spezifische nicht standardmäßige AppDomain einfügen, welche die UI-Elemente enthält, die Sie angeben möchten.
MarshalByRefObject
abgeleitet ist und die Funktion enthält, die Sie in nicht standardmäßigen AppDomains ausführen möchten:public class CrossAppDomainRunner : MarshalByRefObject
{
public void Execute(IntPtr controlHandle)
{
// Implementation of the method that will be executed in the target AppDomain
Trace.WriteLine("Sunt in " + AppDomain.CurrentDomain.FriendlyName);
Control foundControl = null;
try
{
foundControl = Control.FromHandle(controlHandle);
}
catch (Exception controlException)
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ An exception occurred while getting the control from handle {controlHandle}. The message is: {controlException.Message}, Win32 Error: {lastWin32Error}");
}
if (foundControl != null)
{
Trace.WriteLine($"+++++ Found control {foundControl.Name} from handle {controlHandle}");
}
else
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ Control NOT found based on handle {controlHandle}, Win32 Error: {lastWin32Error}");
}
}
}
public class CrossAppDomainRunner : MarshalByRefObject
{
public void Execute(IntPtr controlHandle)
{
// Implementation of the method that will be executed in the target AppDomain
Trace.WriteLine("Sunt in " + AppDomain.CurrentDomain.FriendlyName);
Control foundControl = null;
try
{
foundControl = Control.FromHandle(controlHandle);
}
catch (Exception controlException)
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ An exception occurred while getting the control from handle {controlHandle}. The message is: {controlException.Message}, Win32 Error: {lastWin32Error}");
}
if (foundControl != null)
{
Trace.WriteLine($"+++++ Found control {foundControl.Name} from handle {controlHandle}");
}
else
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ Control NOT found based on handle {controlHandle}, Win32 Error: {lastWin32Error}");
}
}
}
Execute
-Funktion, die einen IntPtr
-Parameter erhält. Dieser Parameter enthält den Wert des Steuerelements, das Sie suchen. In diesem Beispiel müssen Sie nur einen IntPtr
-Parameter übergeben, aber in Ihrer speziellen Situation können Sie so viele Parameter hinzufügen, wie Sie möchten.
ICorRuntimeHost
-Schnittstelle von mscoree
. Dazu müssen Sie diese Schnittstelle deklarieren:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace mscoree
{
[CompilerGenerated]
[Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[TypeIdentifier]
[ComImport]
[CLSCompliant(false)]
public interface ICorRuntimeHost
{
void _VtblGap1_11();
void EnumDomains(out IntPtr enumHandle);
void NextDomain([In] IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] out object appDomain);
void CloseEnum([In] IntPtr enumHandle);
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace mscoree
{
[CompilerGenerated]
[Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[TypeIdentifier]
[ComImport]
[CLSCompliant(false)]
public interface ICorRuntimeHost
{
void _VtblGap1_11();
void EnumDomains(out IntPtr enumHandle);
void NextDomain([In] IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] out object appDomain);
void CloseEnum([In] IntPtr enumHandle);
}
}
Sie müssen eine Klasse mit nativen Methoden deklarieren, um das Komponentenobjektmodell (COM) zu initialisieren:
public static class NativeMethods
{
[DllImport("ole32.dll")]
public static extern int CoInitializeEx(IntPtr pvReserved, COINIT dwCoInit);
public enum COINIT : uint
{
/// Initializes the thread for multi-threaded object concurrency.
COINIT_MULTITHREADED = 0x0,
/// Initializes the thread for apartment-threaded object concurrency.
COINIT_APARTMENTTHREADED = 0x2,
// ...
}
}
öffentliche statische Klasse NativeMethods { [DllImport("ole32.dll")] öffentliche statische extern int CoInitializeEx(IntPtr pvReserved, COINIT dwCoInit); öffentliches enum COINIT : uint { /// Initialisiert den Thread für die Gleichzeitigkeit von Objekten mit mehreren Threads.
COINIT_MULTITHREADED = 0x0, /// Initialisiert den Thread für die Parallelität von Objekten mit Appartament-Thread.
COINIT_ApartmentThreaded = 0x2, // ... } }
ICorRunttimeHost
-Objekt abzurufen:
public static ICorRuntimeHost GetCorRuntimeHost()
{
return (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
public static ICorRuntimeHost GetCorRuntimeHost()
{
return (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
GetControlData
wird von der Aktivität Inject .NET Code in der Standard-AppDomain ausgeführt:
public static void GetControlData(Int64 controlHandle, out string response)
{
//initialising COM
NativeMethods.CoInitializeEx(IntPtr.Zero, NativeMethods.COINIT.COINIT_MULTITHREADED);
mscoree.ICorRuntimeHost host = null;
try
{
host = (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
catch (COMException comEx)
{
Trace.WriteLine($"COMException: {comEx.Message}, HRESULT: {comEx.ErrorCode}");
}
catch (Exception ex)
{
// Handle other exceptions
Trace.WriteLine($"Exception: {ex.Message}");
}
IntPtr enumHandle = IntPtr.Zero;
try
{
//now that we have ICorRuntimeHost object we can use it to enumerate the other domains
host.EnumDomains(out enumHandle);
object domain = null;
host.NextDomain(enumHandle, out domain);
while (domain != null)
{
//for each appdomain obtained
AppDomain appDomain = (AppDomain)domain;
//appDomain.BaseDirectory; - you might want to copy your dll
//in the appDomain.BaseDirectory cause otherwise it might not find
//the assembly
ObjectHandle handle = appDomain.CreateInstance(
typeof(CrossAppDomainRunner).Assembly.FullName,
typeof(CrossAppDomainRunner).FullName);
// Unwrap to get the actual object
var runnerProxy = handle.Unwrap();
// Use reflection to call the Execute method
MethodInfo executeMethod = runnerProxy.GetType().GetMethod("Execute", new Type[] { typeof(IntPtr) });
//pass parameters as new object[]
executeMethod.Invoke(runnerProxy, new object[] { new IntPtr(controlHandle) });
//go to next appdomain
host.NextDomain(enumHandle, out domain);
if (domain == null)
break;
}
}
finally
{
if (host != null)
{
if (enumHandle != IntPtr.Zero)
{
host.CloseEnum(enumHandle);
}
Marshal.ReleaseComObject(host);
}
}
response = string.Empty;
}
public static void GetControlData(Int64 controlHandle, out string response)
{
//initialising COM
NativeMethods.CoInitializeEx(IntPtr.Zero, NativeMethods.COINIT.COINIT_MULTITHREADED);
mscoree.ICorRuntimeHost host = null;
try
{
host = (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
catch (COMException comEx)
{
Trace.WriteLine($"COMException: {comEx.Message}, HRESULT: {comEx.ErrorCode}");
}
catch (Exception ex)
{
// Handle other exceptions
Trace.WriteLine($"Exception: {ex.Message}");
}
IntPtr enumHandle = IntPtr.Zero;
try
{
//now that we have ICorRuntimeHost object we can use it to enumerate the other domains
host.EnumDomains(out enumHandle);
object domain = null;
host.NextDomain(enumHandle, out domain);
while (domain != null)
{
//for each appdomain obtained
AppDomain appDomain = (AppDomain)domain;
//appDomain.BaseDirectory; - you might want to copy your dll
//in the appDomain.BaseDirectory cause otherwise it might not find
//the assembly
ObjectHandle handle = appDomain.CreateInstance(
typeof(CrossAppDomainRunner).Assembly.FullName,
typeof(CrossAppDomainRunner).FullName);
// Unwrap to get the actual object
var runnerProxy = handle.Unwrap();
// Use reflection to call the Execute method
MethodInfo executeMethod = runnerProxy.GetType().GetMethod("Execute", new Type[] { typeof(IntPtr) });
//pass parameters as new object[]
executeMethod.Invoke(runnerProxy, new object[] { new IntPtr(controlHandle) });
//go to next appdomain
host.NextDomain(enumHandle, out domain);
if (domain == null)
break;
}
}
finally
{
if (host != null)
{
if (enumHandle != IntPtr.Zero)
{
host.CloseEnum(enumHandle);
}
Marshal.ReleaseComObject(host);
}
}
response = string.Empty;
}
Im obigen Beispiel wird der Code in alle AppDomains eingefügt. Sobald Sie die AppDomain herausgefunden haben, in der sich die UI-Elemente befinden, die Sie angeben möchten, können Sie alle AppDomains aufzählen, aber Code nur in die erforderliche AppDomain einfügen.