dotnet/wpf · error · DirectoryNotFoundException
SR.DirectoryNotFoundExceptionWithFileName
Error message
SR.DirectoryNotFoundExceptionWithFileName
What it means
Util.ThrowWin32Exception maps Win32 error codes from font-file operations to typed exceptions; ERROR_PATH_NOT_FOUND yields DirectoryNotFoundException with SR.DirectoryNotFoundExceptionWithFileName, meaning the directory portion of the font path does not exist.
Solutions
- Verify the directory portion of the font path exists (Directory.Exists) before loading.
- Correct the font Uri path.
- Fix deployment/packaging so the fonts directory ships with the app.
- If using a UNC path, verify the share is reachable.
Example fix
// before
var gt = new GlyphTypeface(new Uri(@"C:\Fonts\Old\App.ttf")); // Fonts\Old missing
// after
string path = @"C:\Fonts\New\App.ttf";
if (!Directory.Exists(Path.GetDirectoryName(path))) throw new InvalidOperationException("Font directory missing");
var gt = new GlyphTypeface(new Uri(path)); Defensive patterns
Strategy: validation
Validate before calling
string dir = Path.GetDirectoryName(fontUri.LocalPath);
if (fontUri.IsFile && !Directory.Exists(dir))
throw new InvalidOperationException($"Font directory missing: {dir}"); Type guard
static bool FontDirectoryExists(Uri fontUri) =>
fontUri.IsFile && Directory.Exists(Path.GetDirectoryName(fontUri.LocalPath)); Try / catch
try
{
var gt = new GlyphTypeface(fontUri);
}
catch (DirectoryNotFoundException ex)
{
Log($"Font directory missing: {ex.Message}");
// correct deployment or fall back
} Prevention
- Validate the parent directory of font paths at startup.
- Keep font assets under the application's own folders.
- Detect moved/renamed shares with a health check before font loading.
When it happens
Trigger: Opening a font source whose parent directory is missing (Win32 error 3), routed through Util.ThrowWin32Exception from font file open/mapping code.
Common situations: Typo in the directory part of a font:// or file:// Uri; deployment layout changed so the fonts folder is absent; drive letter or share renamed.
Related errors
- SR.FileNotFoundExceptionWithFileName
- SR.IOExceptionWithFileName
- SR.PathTooLongExceptionWithFileName
- SR.UnauthorizedAccessExceptionWithFileName
- ArgumentOutOfRangeException(nameof(offset))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ac6fc16a672c66c8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontCacheUtil.cs:751
return ca - cb;
}
/// <summary>
/// This function performs job similar to CLR's internal __Error.WinIOError function:
/// it maps win32 errors from file I/O to CLR exceptions and includes string where possible.
/// However, we're interested only in errors when opening a file for reading.
/// </summary>
/// <param name="errorCode">Win32 error code.</param>
/// <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;View on GitHub (pinned to 81131a70a4)