diff --git a/packages/native-helpers/windows-helper/src/Services/UIAutomationService.cs b/packages/native-helpers/windows-helper/src/Services/UIAutomationService.cs
index 97ca4dd..1e6f974 100644
--- a/packages/native-helpers/windows-helper/src/Services/UIAutomationService.cs
+++ b/packages/native-helpers/windows-helper/src/Services/UIAutomationService.cs
@@ -129,15 +129,30 @@ namespace WindowsHelper.Services
var tp = textPattern as TextPattern;
if (tp != null)
{
- var selection = tp.GetSelection();
- if (selection.Length > 0)
+ try
{
- var range = selection[0];
- context.TextSelection = new TextSelection
+ var selection = tp.GetSelection();
+ if (selection != null && selection.Length > 0)
{
- SelectedText = range.GetText(-1),
- IsEditable = context.IsEditable
- };
+ var range = selection[0];
+ var selectedText = SafeGetTextFromRange(range);
+ if (selectedText != null)
+ {
+ context.TextSelection = new TextSelection
+ {
+ SelectedText = selectedText,
+ IsEditable = context.IsEditable
+ };
+ }
+ }
+ }
+ catch (COMException ex)
+ {
+ LogToStderr($"Error getting text selection: {ex.Message}");
+ }
+ catch (InvalidOperationException ex)
+ {
+ LogToStderr($"Error getting text selection: {ex.Message}");
}
}
}
@@ -270,7 +285,7 @@ namespace WindowsHelper.Services
// Try Text pattern
if (element.TryGetCurrentPattern(TextPattern.Pattern, out object textPattern))
{
- return (textPattern as TextPattern)?.DocumentRange.GetText(-1);
+ return SafeGetDocumentText(textPattern as TextPattern);
}
// Try RangeValue pattern
@@ -297,7 +312,7 @@ namespace WindowsHelper.Services
var vp = valuePattern as ValuePattern;
return vp != null && !vp.Current.IsReadOnly;
}
-
+
// Check if it's an editable text control
if (element.Current.ControlType == ControlType.Edit ||
element.Current.ControlType == ControlType.Document)
@@ -309,10 +324,48 @@ namespace WindowsHelper.Services
{
// Ignore pattern errors
}
-
+
return false;
}
-
+
+ ///
+ /// Safely retrieves text from a TextPatternRange, handling COM exceptions that can occur
+ /// when the underlying element becomes unavailable.
+ ///
+ private string? SafeGetTextFromRange(TextPatternRange? range, int maxLength = -1)
+ {
+ if (range == null) return null;
+
+ try
+ {
+ return range.GetText(maxLength);
+ }
+ catch (COMException ex)
+ {
+ LogToStderr($"SafeGetTextFromRange COMException: {ex.Message}");
+ return null;
+ }
+ catch (ElementNotAvailableException ex)
+ {
+ LogToStderr($"SafeGetTextFromRange ElementNotAvailable: {ex.Message}");
+ return null;
+ }
+ catch (InvalidOperationException ex)
+ {
+ LogToStderr($"SafeGetTextFromRange InvalidOperation: {ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// Safely retrieves the document text from a TextPattern.
+ ///
+ private string? SafeGetDocumentText(TextPattern? textPattern, int maxLength = -1)
+ {
+ if (textPattern?.DocumentRange == null) return null;
+ return SafeGetTextFromRange(textPattern.DocumentRange, maxLength);
+ }
+
private void LogToStderr(string message)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");