{"record":{"id":"9b4882d9654f783e","repo":"dotnet/wpf","slug":"elementnotavailableexception-misc","errorCode":null,"errorMessage":"ElementNotAvailableException","messagePattern":"ElementNotAvailableException","errorType":"exception","errorClass":"ElementNotAvailableException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Misc.cs","lineNumber":702,"sourceCode":"            int lastWin32Error = 0;\n            int style = UnsafeNativeMethods.GetWindowLong(hwnd, NativeMethods.GWL_STYLE, out lastWin32Error);\n\n            if (style == 0)\n            {\n                ThrowWin32ExceptionsIfError(lastWin32Error);\n            }\n\n            return style;\n        }\n\n        internal static uint GetWindowThreadProcessId(IntPtr hwnd, out uint processId)\n        {\n            // GetWindowThreadProcessId does use SetLastError().  So a call to GetLastError() would be meanless.\n            uint threadId = UnsafeNativeMethods.GetWindowThreadProcessId(hwnd, out processId);\n\n            if (threadId == 0)\n            {\n                throw new ElementNotAvailableException();\n            }\n\n            return threadId;\n        }\n\n        internal static short GlobalAddAtom(string atomName)\n        {\n            short atom = UnsafeNativeMethods.GlobalAddAtom(atomName);\n            int lastWin32Error = Marshal.GetLastWin32Error();\n            if (atom == 0)\n            {\n                ThrowWin32ExceptionsIfError(lastWin32Error);\n            }\n            return atom;\n        }\n\n        internal static short GlobalDeleteAtom(short atom)\n        {","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Misc.cs#L684-L720","documentation":"Misc.GetWindowThreadProcessId throws ElementNotAvailableException when UnsafeNativeMethods.GetWindowThreadProcessId returns threadId == 0, which means the HWND is no longer valid — the window has been destroyed. The library signals this as an unavailable element rather than a raw Win32 failure.","triggerScenarios":"Calling GetWindowThreadProcessId(hwnd) on a destroyed or never-created window handle — commonly when reading element runtime-id/process properties after the target window closed.","commonSituations":"App under automation exits mid-test; cached HWND from an earlier enumeration is used after the window closed; invalid IntPtr passed to UIA client helpers.","solutions":["Validate the handle with IsWindow(hwnd) before calling UIA APIs on it","Re-acquire the element from a fresh tree walk instead of reusing cached providers","Catch ElementNotAvailableException around property access and treat it as 'element gone'","Fix lifetime management in your automation so handles are not outlived by their windows"],"exampleFix":"// before\nuint threadId = Misc.GetWindowThreadProcessId(hwnd, out processId); // throws if hwnd dead\n// after\nif (SafeNativeMethods.IsWindow(hwnd))\n{\n    uint threadId = Misc.GetWindowThreadProcessId(hwnd, out processId);\n}\nelse\n{\n    processId = 0; // window destroyed; skip or re-walk tree\n}","handlingStrategy":"validation","validationCode":"if (!SafeNativeMethods.IsWindow(hwnd)) { processId = 0; return; } // window destroyed\nvar pid = Misc.GetWindowThreadProcessId(hwnd, out _);","typeGuard":"bool IsValidWindow(IntPtr h) => h != IntPtr.Zero && IsWindow(h);","tryCatchPattern":"try { tid = Misc.GetWindowThreadProcessId(hwnd, out pid); } catch (ElementNotAvailableException) { pid = 0; /* window closed */ }","preventionTips":["Validate HWNDs with IsWindow immediately before every native call","Bind element lifetime to window lifetime notifications","Avoid holding HWNDs across operations that can close the app","Handle app exit during automation as a normal, expected condition"],"tags":["ui-automation","stale-hwnd","window-destroyed","win32"],"backgroundTag":"entity-not-found","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"}