{"record":{"id":"36b174e3e26212cc","repo":"dotnet/wpf","slug":"elementnotavailableexception-commonxsendmessage","errorCode":null,"errorMessage":"ElementNotAvailableException","messagePattern":"ElementNotAvailableException","errorType":"exception","errorClass":"ElementNotAvailableException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/CommonXSendMessage.cs","lineNumber":74,"sourceCode":"        //                     the max size for the string.\n        // Param \"hwnd\" the Window Handle\n        // Param \"uMsg\" the Windows Message\n        // Param \"wParam\" the Windows wParam\n        // Param \"lParam\" a pointer to a struct allocated on the stack\n        // Param \"cbSize\" the size of the structure\n        // Param \"pszText\" the address of a pointer to a string located with the structure referenced by the lParam\n        // Param \"maxLength\" the size of the string\n        // Param \"remoteBitness\" the bitness of the pointer contained within pszText\n        internal static unsafe string GetTextWithinStructureRemoteBitness(\n            IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam, int cbSize,\n            IntPtr pszText, int maxLength, ProcessorTypes remoteBitness, bool ignoreSendResult)\n        {\n            using (SafeProcessHandle hProcess = new SafeProcessHandle(hwnd))\n            {\n                if (hProcess.IsInvalid)\n                {\n                    // assume that the hwnd was bad\n                    throw new ElementNotAvailableException();\n                }\n\n                using (RemoteMemoryBlock rmem = new RemoteMemoryBlock(cbSize + (maxLength + 1) * sizeof(char), hProcess))\n                {\n                    // Allocate the space for the object as well as the string\n                    // Ensure proper allocation\n                    if (rmem.IsInvalid)\n                    {\n                        return \"\";\n                    }\n\n                    // Force the string to be zero terminated\n\n                    IntPtr remoteTextArea = new IntPtr((byte*)rmem.Address.ToPointer() + cbSize);\n                    if (remoteBitness == ProcessorTypes.Processor32Bit)\n                    {\n                        // When the structure will be sent to a 32-bit process,\n                        // pszText points to an int, not an IntPtr.","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/CommonXSendMessage.cs#L56-L92","documentation":"GetTextWithinStructureRemoteBitness needs to read text from the process that owns the target hwnd via cross-process memory. If the SafeProcessHandle opened from the hwnd is invalid, the target window/process no longer exists, so UIAutomation throws ElementNotAvailableException — the element the client addressed is gone.","triggerScenarios":"Calling GetTextWithinStructure (which dispatches to GetTextWithinStructureRemoteBitness) for an hwnd whose process has exited or for which a process handle cannot be opened; SafeProcessHandle.IsInvalid is true immediately after construction.","commonSituations":"Automating an application that crashes or exits mid-run; racing window close during UI test teardown; elevated/protected processes that cannot be opened from a lower-integrity client; passing a stale hwnd captured earlier.","solutions":["Verify the target element/window is still alive (IsOffscreen/Current.NativeWindowHandle, or re-find the element) before calling text retrieval.","Catch ElementNotAvailableException and re-acquire the element from the desktop tree, then retry once.","Check Process.GetProcessById / handle validity for the hwnd's PID before issuing the cross-process call.","Ensure your client runs with sufficient integrity/privilege to open the target process (UIAccess, same elevation)."],"exampleFix":"// before\nstring text = GetTextWithinStructure(hwnd, ...); // throws if hwnd's process is dead\n// after\nif (IsWindow(hwnd))\n{\n    try { text = GetTextWithinStructure(hwnd, ...); }\n    catch (ElementNotAvailableException) { text = null; }\n}","handlingStrategy":"try-catch","validationCode":"[DllImport(\"user32.dll\")] static extern bool IsWindow(IntPtr hWnd);\n// before the call:\nif (!IsWindow(hwnd)) return null;","typeGuard":"static bool IsHwndUsable(IntPtr hwnd) => hwnd != IntPtr.Zero && IsWindow(hwnd);","tryCatchPattern":"try { text = GetTextWithinStructure(hwnd, ...); }\ncatch (ElementNotAvailableException) { text = null; /* re-acquire element */ }","preventionTips":["Check IsWindow/process liveness before cross-process UIA calls","Do not hold hwnds across application restarts; re-resolve each session","Match client and target elevation/integrity so process handles open","Catch ElementNotAvailableException on every remote-element property read"],"tags":["ui-automation","cross-process","stale-hwnd","process-handle"],"backgroundTag":"element-not-available","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}