QL-Win/QuickLook · error · FileNotFoundException

Compound file not found.

Error message

Compound file not found.

What it means

Thrown by CompoundFileExtractor.ExtractToDirectory when File.Exists(compoundFilePath) is false. This is a FileNotFoundException whose FileName carries the missing path. It fires before any OLE parsing begins.

Source

Thrown at QuickLook.Plugin/QuickLook.Plugin.ArchiveViewer/CompoundFileBinary/CompoundFileExtractor.cs:48

public static partial class CompoundFileExtractor
{
    /// <summary>
    /// Extracts all streams and storages from the compound file at <paramref name="compoundFilePath"/>
    /// into the specified <paramref name="destinationDirectory"/>. Directory structure inside the compound
    /// file is preserved.
    /// </summary>
    /// <param name="compoundFilePath">Path to the compound file (OLE compound file / structured storage).</param>
    /// <param name="destinationDirectory">Destination directory to write extracted files and directories to. If it does not exist it will be created.</param>
    public static void ExtractToDirectory(string compoundFilePath, string destinationDirectory)
    {
        if (!Directory.Exists(destinationDirectory))
        {
            Directory.CreateDirectory(destinationDirectory);
        }

        // Ensure the compound file exists
        if (!File.Exists(compoundFilePath))
            throw new FileNotFoundException("Compound file not found.", compoundFilePath);

        // Validate magic header for OLE compound file: D0 CF 11 E0 A1 B1 1A E1
        byte[] magicHeader = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
        byte[] header = new byte[8];
        using (FileStream fs = new(compoundFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            int read = fs.Read(header, 0, header.Length);
            if (read < header.Length || !header.SequenceEqual(magicHeader))
            {
                throw new InvalidDataException("The specified file does not appear to be an OLE Compound File (invalid header).");
            }
        }

        // Open the compound file as an IStorage implementation wrapped by DisposableIStorage.
        using DisposableIStorage storage = new(compoundFilePath, STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE, IntPtr.Zero);
        IEnumerator<STATSTG> enumerator = storage.EnumElements();

        // Enumerate all elements (streams and storages) at the root of the compound file.

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Check File.Exists(compoundFilePath) before calling ExtractToDirectory and surface a clear message.
  2. Verify the path is absolute and correctly expanded (Environment.ExpandEnvironmentVariables).
  3. For network paths, confirm the share is reachable before processing.
  4. Catch FileNotFoundException and prompt the user to reselect the file.

Example fix

// before
CompoundFileExtractor.ExtractToDirectory(path, dest);

// after
if (!File.Exists(path))
    throw new FileNotFoundException($"Compound file not found: {path}", path);
CompoundFileExtractor.ExtractToDirectory(path, dest);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the compound file exists before extraction.
public static void SafeExtract(string compoundFilePath, string dest)
{
    if (!File.Exists(compoundFilePath))
        throw new FileNotFoundException($"Compound file not found: {compoundFilePath}", compoundFilePath);
    CompoundFileExtractor.ExtractToDirectory(compoundFilePath, dest);
}

Try / catch

try { CompoundFileExtractor.ExtractToDirectory(path, dest); }
catch (FileNotFoundException ex) when (ex.FileName == path)
{
    // Source file is gone; prompt user to reselect.
}

Prevention

When it happens

Trigger: Calling ExtractToDirectory(compoundFilePath, destinationDirectory) with a path that does not exist: deleted file, wrong path, network share offline, or a relative path resolved against an unexpected working directory.

Common situations: User deletes/moves the source file between selection and extraction; a stale path cached from a previous run; a UNC path with the share unmounted; a typo or environment-variable expansion that yielded a non-existent path.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/3775ba8c493d3b7b. Report an issue: GitHub.