beeradmoore/dlss-swapper · error · Exception
Failed to get result from file open dialog.
Error message
Failed to get result from file open dialog.
What it means
In FileSystemHelper.OpenFileInternal (multi-select path), each item of the ShellItemArray returned by the IFileOpenDialog is fetched with GetItemAt. If any item comes back null the helper cannot produce a path for it and throws this exception. It indicates the Shell gave a result collection containing an unusable entry.
Solutions
- Treat null items as skippable: continue enumerating remaining items instead of failing the whole operation.
- GetDisplayName on each item inside try/catch and skip items whose SIGDN_FILESYSPATH cannot be resolved.
- Validate the selection before closing (filter to filesystem items) if the dialog configuration allows it.
- Log the index and count when skipping to aid diagnosing shell-provided bad items.
Example fix
// before
ppsiArray.GetItemAt(i, out var ppsi);
if (ppsi is null) throw new Exception("Failed to get result from file open dialog.");
// after
ppsiArray.GetItemAt(i, out var ppsi);
if (ppsi is null) continue; // skip unavailable item instead of failing all selected files Defensive patterns
Strategy: type-guard
Validate before calling
// no pre-call validation possible for shell internals; guard the item after GetItemAt
ppsiArray.GetItemAt(i, out var ppsi);
if (ppsi is null) { skipped++; continue; } Type guard
static bool IsUsableShellItem(IShellItem? item) => item is not null;
Try / catch
try
{
CollectDialogItems(ppsiArray, count, results);
}
catch (Exception ex) when (ex.Message == "Failed to get result from file open dialog.")
{
// return whatever paths were collected so far instead of failing all
} Prevention
- Skip null items and log them rather than aborting a multi-select result.
- Check network/removable paths for availability before relying on them.
- Resolve SIGDN_FILESYSPATH defensively; some shell items have no filesystem path.
When it happens
Trigger: During enumeration of a multi-file selection, ppsiArray.GetItemAt(i, out ppsi) succeeds but yields a null IShellItem at index i — e.g. an item that was removed or became unavailable between selection and retrieval (network share/removed device), or a shell namespace item without a filesystem representation.
Common situations: User selects files on a network drive or removable media that disconnects before the dialog result is processed; virtual shell items (This PC, libraries) surfaced into the result; Windows shell edge cases with unusual file pickers.
AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15).
Data as JSON: /api/errors/dd4fe3b7306729a9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Helpers/FileSystemHelper.cs:187
fileOpenDialog.Show(new HWND(hWnd));
var results = new List<string>();
if (pickMultiple)
{
fileOpenDialog.GetResults(out var ppsiArray);
unsafe
{
ppsiArray.GetCount(out uint count);
for (uint i = 0; i < count; ++i)
{
ppsiArray.GetItemAt(i, out var ppsi);
if (ppsi is null)
{
throw new Exception("Failed to get result from file open dialog.");
}
PWSTR filename;
ppsi.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, &filename);
var pathName = filename.ToString();
results.Add(pathName);
}
}
}
else
{
fileOpenDialog.GetResult(out var ppsi);
if (ppsi is null)
{
throw new Exception("Failed to get result from file open dialog.");
}
View on GitHub (pinned to ab9b1e2d4b)