- Überblick
- UI-Automatisierung (UI Automation)
- 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
- ST-DBP-021 – Hartcodiertes Timeout
- 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
- SY-USG-013 – Private Datei aufrufen
- SY-USG-014 – Falsche Platzhalter für Ausführungsvorlage
- Mit UI-Automatisierung automatisierte Anwendungen und Technologien
- UiPath-Browsermigrationstool
- Computer Vision Recorder
- Klicken (Click)
- Darauf zeigen (Hover)
- Sicheren Text eingeben (Type Secure Text)
- Hotkey senden (Send Hotkey)
- Eingeben in (Type Into)
- Prüfen (Check)
- Objekt auswählen (Select Item)
- Mehrere Objekte auswählen (Select Multiple Items)
- Text erhalten (Get Text)
- Text einstellen (Set Text)
- Aktivieren (Activate)
- Markieren (Highlight)
- Fokus legen auf (Set Focus)
- Ankerbasis (Anchor Base)
- Kontextbewusster Anker
- Relatives Element finden (Find Relative Element)
- Auf Bildschirm anzeigen (Indicate On Screen)
- Element vorhanden (Element Exists)
- Element finden (Find Element)
- Warten, bis Element verschwindet (Wait Element Vanish)
- Untergeordnete Elemente finden (Find Children)
- Vorgänger-Element erhalten (Get Ancestor)
- Elementumfang (Element Scope)
- Attribut erhalten (Get Attribute)
- Ausschneidebereich einstellen (Set Clipping Region)
- Position erhalten (Get Position)
- Screenshot anfertigen (Take Screenshot)
- Attribut abwarten (Wait Attribute)
- Auf Element erscheinen (On Element Appear)
- Auf Element verschwinden (On Element Vanish)
- Text anklicken (Click Text)
- Text beim Darauf zeigen (Hover Text)
- Textposition finden (Find Text Position)
- Volltext erhalten (Get Full Text)
- Sichtbaren Text erhalten (Get Visible Text)
- Strukturierte Daten extrahieren (Extract Structured Data)
- Text vorhanden (Text Exists)
- OCR-Text anklicken (Click OCR Text)
- Auf OCR-Text zeigen (Hover OCR Text)
- OCR-Text erhalten (Get OCR Text)
- OCR-Textposition finden (Find OCR Text Position)
- Microsoft OCR
- Microsoft Project Oxford Online OCR
- Microsoft Azure ComputerVision OCR
- Tesseract OCR
- Google Cloud Vision OCR
- OCR-Text vorhanden (OCR Text Exists)
- Bild anklicken (Click Image)
- Auf Bild zeigen (Hover Image)
- Bildübereinstimmung finden (Find Image Matches)
- Bild vorhanden (Image Exists)
- Bild finden (Find Image)
- Warten, bis Bild verschwindet (Wait Image Vanish)
- Auf Bild erscheinen (On Image Appear)
- Auf Bild verschwinden (On Image Vanish)
- Bild laden (Load Image)
- Bild speichern (Save Image)
- Browser anhängen (Attach Browser)
- Registerkarte schließen (Close Tab)
- Zurück (Go Back)
- Weiter (Go Forward)
- Zur Startseite (Go Home)
- JS-Skript einfügen (Inject JS Script)
- Navigieren zu (Navigate To)
- Browser öffnen (Open Browser)
- Browser aktualisieren (Refresh Browser)
- Web-Attribut setzen (Set Web Attribute)
- Fenster anhängen (Attach Window)
- Fenster schließen (Close Window)
- Aktives Fenster abrufen (Get Active Window)
- Fenster ausblenden (Hide Window)
- Fenster maximieren (Maximize Window)
- Fenster minimieren (Minimize Window)
- Fenster verschieben (Move Window)
- Fenster wiederherstellen (Restore Window)
- Fenster anzeigen (Show Window)
- Export UI Tree
- ActiveX-Methode aufrufen
- .NET-Code einfügen
- Trigger anklicken (Click Trigger)
- Tastendruck-Trigger (Key Press Trigger)
- Bild-Trigger anklicken (Click Image Trigger)
- System-Trigger (System Trigger)
- Hotkey-Trigger (Hotkey Trigger)
- Maus-Trigger (Mouse Trigger)
- Ereignisinfo erhalten (Get Event Info)
- Ereignisse überwachen (Monitor Events)
- Quellelement erhalten (Get Source Element)
- Benutzerereignis wiedergeben (Replay User Event)
- Benutzeingabe blockieren (Block User Input)
- Vordergrund verwenden
- Element Attribute Change Trigger
- Element State Change Trigger
- Textfeld (Callout)
- Ausgewählten Text kopieren (Copy Selected Text)
- Aus Zwischenablage erhalten (Get From Clipboard)
- Auf Zwischenablage setzen (Set To Clipboard)
- Anwendung schließen (Close Application)
- Anwendung öffnen (Open Application)
- Prozess starten (Start Process)
- Passwort erhalten (Get Password)
- Tooltip
- Click Picture on Screen
- Click Toolbar Button
- Read Statusbar
- Select Dates In Calendar
- Select Menu Item
- Expand Tree
- Call Transaction
- SAP Logon
- SAP Login
- Table Cell Scope
- SAP Session Attributes Change Trigger
- Expand ALV Tree
- Expand ALV Hierarchical Table
- Use Application/Browser
- Check App State
- Check/Uncheck
- Klicken (Click)
- Extract Table Data
- Text erhalten (Get Text)
- Get URL
- Zu URL wechseln
- Markieren (Highlight)
- Darauf zeigen (Hover)
- Tastenkombinationen
- Navigate Browser
- Objekt auswählen (Select Item)
- Screenshot anfertigen (Take Screenshot)
- Eingeben in (Type Into)
- Attribut erhalten (Get Attribute)
- Get Browser Data
- Set Browser Data
- Mouse Scroll
- Inject Js Script
- Ziehen und Ablegen
- For Each UI Element
- Application event trigger
- Click Event Trigger
- Keypress Event Trigger
- Text einstellen (Set Text)
- Check Element
- Formular ausfüllen
- 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)
- Ist aktiviert
- 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
- 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
- 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
- Muster zeichnen
- Terminal
- Versionshinweise
- Über das Terminal-Aktivitätspaket
- Projektkompatibilität
- Terminalsitzung (Terminal Session)
- Bildschirmbereich erhalten (Get Screen Area)
- Text an Position erhalten (Get Text at Position)
- Get Color At Position
- Feld an Position erhalten (Get Field at Position)
- Feld an Position setzen (Set Field at Position)
- Warte auf Text an Position (Wait Text at Position)
- Tasten senden (Send Keys)
- Cursor bewegen (Move Cursor)
- Sichere Tasten senden (Send Keys Secure)
- Text erhalten (Get Text)
- Find Text
- Move Cursor to Text
- Strg-Taste senden (Send Control Key)
- Feld erhalten (Get Field)
- Warte auf Bildschirmtext (Wait Screen Text)
- Warte auf Feldtext (Wait Field Text)
- Feld setzen (Set Field)
.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.
The Inject .NET Code activity injects code only in the default AppDomain.
Some applications are structured in a way that the elements you may require to access or manipulate are not located within the default AppDomain, so injecting code in the default AppDomain is not enough. So, if the UI elements you want to indicate are located in another AppDomain, they are not available to the injected code.
To fix this, you have to modify the injection process to target the precise AppDomain containing the UI elements. More exactly, you need to inject code from the function that is executed in the default AppDomain into either all the non-default AppDomains or the specific non-default AppDomain containing the UI elements you want to indicate.
MarshalByRefObject
, containing the function you want to execute in non-default AppDomains: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
function that receives an IntPtr
parameter. This parameter contains the value of the control you are trying to find. In this example, you need to pass only an IntPtr
parameter, but in your particular situation, you can add as many parameters as you want.
ICorRuntimeHost
interface from mscoree
. To do so, you need to declare that interface:
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);
}
}
You need to declare a class containing native methods to initialise the Component Object Model (COM):
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,
// ...
}
}
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,
// ...
}
}
ICorRunttimeHost
object:
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
is executed by the Inject .NET Code activity in the default AppDomain:
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;
}
The example above injects the code in all AppDomains. Once you find out the AppDomain where the UI elements you want to indicate are located, you can enumerate all AppDomains, but inject code only in the necessary AppDomain.