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

  1. Verify the directory portion of the font path exists (Directory.Exists) before loading.
  2. Correct the font Uri path.
  3. Fix deployment/packaging so the fonts directory ships with the app.
  4. 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

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


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)