BCUninstaller/Bulk-Crap-Uninstaller · error · FormatException

File name must contain an extension separated by a dot. {ful

Error message

File name must contain an extension separated by a dot.
{fullCommand}

What it means

Thrown in the no-dot branch of SeparateArgsFromCommand (SeparateNonDottedCommand). When breakChars are found in the input (so it looks like command + args) but the break index is at position 0 or is not preceded by a space, the parser cannot split a filename from arguments and throws FormatException(Localisation.Error_SeparateArgsFromCommand_NoDot + "\n" + fullCommand) — message: "File name must contain an extension separated by a dot.". The parser expects an executable path with a dotted extension.

Source

Thrown at source/KlocTools/Tools/ProcessTools.cs:279

            var pathRootEnd = pathRoot < 0 ? 0 : pathRoot + 2;

            var breakChars = SeparateArgsFromCommandInvalidChars.Except(new[] { '\\' }).ToArray();

            // Check if there are any invalid path chars before the start we found. If yes, our path is most likely an argument.
            if (pathRootEnd > 0 && fullCommand.IndexOfAny(breakChars, 0, pathRootEnd - 2) >= 0)
                pathRootEnd = 0;
            var breakIndex = fullCommand.IndexOfAny(breakChars, pathRootEnd);

            // If there are no invalid path chars, it's probably just a naked filename or directory path.
            if (breakIndex < 0)
                return new ProcessStartCommand(fullCommand.Trim('"'));

            // The invalid char has to have at least 1 space before it to count as an argument. Otherwise the input is likely garbage.
            if (breakIndex > 0 && fullCommand[breakIndex - 1] == ' ')
                return new ProcessStartCommand(fullCommand.Substring(0, breakIndex - 1).TrimEnd(),
                    fullCommand.Substring(breakIndex));

            throw new FormatException(Localisation.Error_SeparateArgsFromCommand_NoDot + "\n" + fullCommand);
        }

        /// <summary>
        ///     Change default culture info for new threads
        /// </summary>
        /// <param name="culture"></param>
        public static void SetDefaultCulture(CultureInfo culture)
        {
            var type = typeof(CultureInfo);

            if (Environment.Version.Major < 4)
            {
                // Fields used before .Net 4.0
                try
                {
                    type.InvokeMember("m_userDefaultCulture",
                        BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                        null,

View on GitHub (pinned to 608321de98)

Solutions

  1. Ensure the executable portion includes its extension (append ".exe" if appropriate) before parsing.
  2. Insert a space between the executable and its arguments so breakIndex is preceded by ' '.
  3. If the input is intentionally extension-less, skip SeparateArgsFromCommand and treat the whole token as the command.

Example fix

// before
var c = ProcessTools.SeparateArgsFromCommand("myapp-x arg"); // no dot, leading break char

// after
var c = ProcessTools.SeparateArgsFromCommand("myapp-x.exe arg");
Defensive patterns

Strategy: validation

Validate before calling

if (fullCommand.IndexOf('.') < 0)
    throw new ArgumentException("Executable must include a dotted extension");
var cmd = ProcessTools.SeparateArgsFromCommand(fullCommand);

Type guard

static bool HasDottedExtension(string cmd) => cmd != null && cmd.Contains('.');

Try / catch

try { var c = ProcessTools.SeparateArgsFromCommand(cmd); }
catch (FormatException ex) when (ex.Message.Contains("extension separated by a dot"))
{ /* append .exe or treat as bare command */ }

Prevention

When it happens

Trigger: Passing a command whose executable has no file extension (no dot) yet contains argument-separator characters, e.g. "myapp -flag" where 'myapp' has no '.exe', or input beginning with an invalid path char so breakIndex==0.

Common situations: Unix-style or script commands without extensions, bare executable names on PATH passed verbatim, or arguments glued to the filename without a separating space.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/870c104b8ca0b0b8. Report an issue: GitHub.