Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 68 additions & 18 deletions src/Files.App/Services/Windows/WindowsDialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
try
{
using ComPtr<IFileOpenDialog> pDialog = default;
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER).ThrowOnFailure();
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);

// Handle COM creation failure gracefully
if (hr.Failed)
{
App.Logger.LogError("Failed to create IFileOpenDialog COM object. HRESULT: 0x{0:X8}", hr.Value);
return false;
}

if (filters.Length is not 0 && filters.Length % 2 is 0)
{
Expand Down Expand Up @@ -52,24 +59,38 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
pszDefaultFolderPath,
null,
IID.IID_IShellItem,
(void**)pDefaultFolderShellItem.GetAddressOf())
.ThrowOnFailure();
(void**)pDefaultFolderShellItem.GetAddressOf());

// Handle shell item creation failure gracefully
if (hr.Failed)
{
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
// Continue without setting default folder rather than failing completely
}
}

// Folder picker
if (pickFoldersOnly)
pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);

// Set the default folder to open in the dialog
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
// Set the default folder to open in the dialog (only if creation succeeded)
if (pDefaultFolderShellItem.Get() is not null)
{
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
}

// Show the dialog
hr = pDialog.Get()->Show(new HWND(hWnd));
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
return false;

hr.ThrowOnFailure();
// Handle dialog show failure gracefully
if (hr.Failed)
{
App.Logger.LogError("Failed to show FileSaveDialog. HRESULT: 0x{0:X8}", hr.Value);
return false;
}

// Get the file that user chose
using ComPtr<IShellItem> pResultShellItem = default;
Expand All @@ -81,10 +102,14 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]

return true;
}
catch (COMException comEx)
{
App.Logger.LogError(comEx, "COM failure while opening FileOpenDialog. HRESULT: 0x{0:X8}", comEx.HResult);
return false;
}
catch (Exception ex)
{
App.Logger.LogError(ex, "Failed to open FileOpenDialog.");

App.Logger.LogError(ex, "Unexpected error while opening FileOpenDialog.");
return false;
}
}
Expand All @@ -97,7 +122,14 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
try
{
using ComPtr<IFileSaveDialog> pDialog = default;
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER).ThrowOnFailure();
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);

// Handle COM creation failure gracefully
if (hr.Failed)
{
App.Logger.LogError("Failed to create IFileSaveDialog COM object. HRESULT: 0x{0:X8}", hr.Value);
return false;
}

if (filters.Length is not 0 && filters.Length % 2 is 0)
{
Expand Down Expand Up @@ -126,24 +158,38 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
pszDefaultFolderPath,
null,
IID.IID_IShellItem,
(void**)pDefaultFolderShellItem.GetAddressOf())
.ThrowOnFailure();
(void**)pDefaultFolderShellItem.GetAddressOf());

// Handle shell item creation failure gracefully
if (hr.Failed)
{
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
// Continue without setting default folder rather than failing completely
}
}

// Folder picker
if (pickFoldersOnly)
pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);

// Set the default folder to open in the dialog
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
// Set the default folder to open in the dialog (only if creation succeeded)
if (pDefaultFolderShellItem.Get() is not null)
{
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
}

// Show the dialog
hr = pDialog.Get()->Show(new HWND(hWnd));
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
return false;

hr.ThrowOnFailure();
// Handle dialog show failure gracefully
if (hr.Failed)
{
App.Logger.LogError("Failed to show FileSaveDialog. HRESULT: 0x{0:X8}", hr.Value);
return false;
}

// Get the file that user chose
using ComPtr<IShellItem> pResultShellItem = default;
Expand All @@ -155,10 +201,14 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]

return true;
}
catch (COMException comEx)
{
App.Logger.LogError(comEx, "COM failure while opening FileSaveDialog. HRESULT: 0x{0:X8}", comEx.HResult);
return false;
}
catch (Exception ex)
{
App.Logger.LogError(ex, "Failed to open FileSaveDialog.");

App.Logger.LogError(ex, "Unexpected error while opening FileSaveDialog.");
return false;
}
}
Expand Down
Loading