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
- Check which process locks the font file (e.g. Sysinternals handle.exe) and release/close it.
- Retry the operation after the lock is released.
- Copy the font to an app-owned location and load from there.
- 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
- Do not hold font files open in other processes (font viewers, installers).
- Copy fonts to app-local storage before loading.
- Open font files with FileShare.Read to reduce sharing violations.
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
- SR.DirectoryNotFoundExceptionWithFileName
- SR.FileNotFoundExceptionWithFileName
- SR.PathTooLongExceptionWithFileName
- SR.UnauthorizedAccessExceptionWithFileName
- ArgumentNullException
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)