{"record":{"id":"179fc9446e68ced4","repo":"dotnet/wpf","slug":"sr-cursor-loadimagefailure-filename","errorCode":null,"errorMessage":"SR.Cursor_LoadImageFailure (fileName)","messagePattern":"SR\\.Cursor_LoadImageFailure \\(fileName\\)","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Cursor.cs","lineNumber":186,"sourceCode":"                                                                NativeMethods.LR_LOADFROMFILE |\n                                                                (_scaleWithDpi? NativeMethods.LR_DEFAULTSIZE : 0x0000));\n\n            int errorCode = Marshal.GetLastWin32Error();\n            if (_cursorHandle == null || _cursorHandle.IsInvalid)\n            {\n                // LoadImage returns a null handle but does not set\n                // the error condition when icon file is of an incorrect type (e.g., .bmp)\n                //\n                // LoadImage has a bug where it doesn't set the correct error code\n                // when a file is given that is not an ico file.  Icon load fails\n                // but win32 error code is still zero (success).  Thus, we need to\n                // special case this scenario.\n                //\n                if (errorCode != 0)\n                {\n                    if ((errorCode == NativeMethods.ERROR_FILE_NOT_FOUND) || (errorCode == NativeMethods.ERROR_PATH_NOT_FOUND))\n                    {\n                        throw new Win32Exception(errorCode, SR.Format(SR.Cursor_LoadImageFailure, fileName));\n                    }\n                    else\n                    {\n                        throw new Win32Exception(errorCode);\n                    }\n                }\n                else\n                {\n                    throw new ArgumentException(SR.Format(SR.Cursor_LoadImageFailure, fileName));\n                }\n            }\n        }\n\n        //**** DEAD CODE - retained only for compat, if user sets quirk flag  ****\n        private const int BUFFERSIZE = 4096; // the maximum size of the buffer used for loading from stream\n\n        private void LegacyLoadFromStream(Stream cursorStream)\n        {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Cursor.cs#L168-L204","documentation":"Cursor.LoadFromFile calls the Win32 LoadImage API to load a cursor from a .cur/.ani file. When LoadImage fails with ERROR_FILE_NOT_FOUND (2) or ERROR_PATH_NOT_FOUND (3), the code throws a Win32Exception carrying that code with the 'Cursor_LoadImageFailure' message that includes the file name. This tells you the cursor file path passed to the Cursor constructor does not exist on disk.","triggerScenarios":"new Cursor(path) or Cursor.SetCursor with a fileName string where LoadImage returns 0 and errorCode is ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND — i.e. the file or an intermediate directory does not exist.","commonSituations":"Hard-coded paths like 'Cursors\\hand.cur' relative to a working directory that differs at runtime; files not deployed/copied to output directory (missing 'Copy to Output Directory'); missing cursor resource files in packaged ClickOnce/MSIX apps; case or extension typos.","solutions":["Verify the cursor file exists at the exact path using File.Exists before constructing the Cursor.","Use an absolute path or Path.Combine(AppContext.BaseDirectory, relativePath) instead of a working-directory-relative path.","Ensure the .cur/.ani file is included in project output (set Copy to Output Directory = Copy if newer for Content/Resource files).","Fall back to Cursors.Arrow (or another built-in cursor) when the custom file cannot be loaded.","Catch Win32Exception around Cursor construction and surface a friendly message naming the missing file."],"exampleFix":"// before\ncursor = new Cursor(\"Cursors\\\\hand.cur\");\n// after\nstring path = Path.Combine(AppContext.BaseDirectory, \"Cursors\", \"hand.cur\");\ncursor = File.Exists(path) ? new Cursor(path) : Cursors.Arrow;","handlingStrategy":"validation","validationCode":"string path = Path.Combine(AppContext.BaseDirectory, \"Cursors\", \"hand.cur\");\nif (!File.Exists(path)) throw new FileNotFoundException(\"Cursor file missing\", path);\nCursor cursor = new Cursor(path);","typeGuard":"bool IsValidCursorFile(string path) => File.Exists(path) && new FileInfo(path).Length > 0 && string.Equals(Path.GetExtension(path), \".cur\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try { cursor = new Cursor(cursorPath); }\ncatch (Win32Exception ex) when (ex.NativeErrorCode == 2 || ex.NativeErrorCode == 3)\n{ logger.LogWarning(\"Cursor file not found: {Path}\", cursorPath); cursor = Cursors.Arrow; }","preventionTips":["Always resolve cursor paths against AppContext.BaseDirectory, not the current working directory.","Set 'Copy to Output Directory' on cursor content files and verify deployment artifacts.","Check File.Exists before every custom Cursor construction.","Log the resolved absolute path in the failure handler for diagnosis."],"tags":["wpf","cursor","win32","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}