dotnet/wpf · error · IOException

SR.IOExceptionWithFileName

Error message

SR.IOExceptionWithFileName

What it means

The default branch of Util.ThrowWin32Exception wraps any unrecognized Win32 error into IOException with SR.IOExceptionWithFileName and an HRESULT made from the error code, for font-file operations that fail for reasons not covered by the specific cases.

Solutions

  1. Check which process locks the font file (e.g. Sysinternals handle.exe) and release/close it.
  2. Retry the operation after the lock is released.
  3. Copy the font to an app-owned location and load from there.
  4. Inspect the HResult/inner Win32 error to identify the specific failure.

Example fix

// before
var gt = new GlyphTypeface(new Uri(path)); // IOException: file locked by font viewer
// after
try { var gt = new GlyphTypeface(new Uri(path)); }
catch (IOException ex) {
    // fall back to in-memory copy so the file need not stay open
    byte[] bytes = File.ReadAllBytes(path);
    var gt = new GlyphTypeface(new MemoryStream(bytes).AsRandomAccessStreamLikeWrapper());
}
Defensive patterns

Strategy: try-catch

Validate before calling

try { using var fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); }
catch (IOException) { /* file locked or unreadable — copy or retry later */ }

Try / catch

try
{
    var gt = new GlyphTypeface(fontUri);
}
catch (IOException ex)
{
    Log($"Font I/O failed: {ex.Message}");
    // inspect ex.HResult for the underlying Win32 error; retry or fall back
}

Prevention

When it happens

Trigger: A font file operation (open/create-file-mapping path in FontSource) returning a Win32 error other than 2, 3, 5, or 206 — e.g. sharing violation (32), disk error, or file in use — routed to the default case.

Common situations: Font file locked by another process (font viewer/installer), sharing violations, disk/media errors, file on unavailable removable media.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/b3f2508b93cf0ca4. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontCacheUtil.cs:760

        /// <param name="fileName">File name string.</param>
        internal static void ThrowWin32Exception(int errorCode, string fileName)
        {
            switch (errorCode)
            {
                case NativeMethods.ERROR_FILE_NOT_FOUND:
                    throw new FileNotFoundException(SR.Format(SR.FileNotFoundExceptionWithFileName, fileName), fileName);

                case NativeMethods.ERROR_PATH_NOT_FOUND:
                    throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFoundExceptionWithFileName, fileName));

                case NativeMethods.ERROR_ACCESS_DENIED:
                    throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccessExceptionWithFileName, fileName));

                case NativeMethods.ERROR_FILENAME_EXCED_RANGE:
                    throw new PathTooLongException(SR.Format(SR.PathTooLongExceptionWithFileName, fileName));

                default:
                    throw new IOException(SR.Format(SR.IOExceptionWithFileName, fileName), NativeMethods.MakeHRFromErrorCode(errorCode));
            }
        }

        internal static Exception ConvertInPageException(FontSource fontSource, SEHException e)
        {
            string fileName;
            if (fontSource.IsFile)
            {
                fileName = fontSource.Uri.LocalPath;
            }
            else
            {
                fileName = fontSource.GetUriString();
            }

            return new IOException(SR.Format(SR.IOExceptionWithFileName, fileName), e);
        }
    }

View on GitHub (pinned to 81131a70a4)