-
Notifications
You must be signed in to change notification settings - Fork 331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileOpenPicker PickMultipleFilesAsync Break in WinUI3 Desktop #467
Comments
@Scottj1s and @stevenbrix is this cswinrt related? |
See #466 for more information on why this doesn't work and the workaround. |
Hi @codendone, while the # 4192 workaround does work for the single file picker, the workaround not seem to work for the multiple file picker. As soon as I changed it to this
It crashes, just like my example solution that we provided as a Preview3 solution, and now as a Preview4 solution. |
@eleanorleffler thanks opening the bug and share the code. I could repro this. I noticed that the doc of this API has the UWP label. I don't know if this means that this API won't work in Win32 apps.
I need help from the Project Reunion folks, this API is out of the WinUI domain. @jonwis, can you help us to know what is happening here? We get:
Below you can find the code snipped: public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private async void fileOpenPickerMultipleButton_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker picker = new FileOpenPicker();
IInitializeWithWindow initializeWithWindowWrapper = picker.As<IInitializeWithWindow>();
var hwnd = this.As<IWindowNative>().WindowHandle;
initializeWithWindowWrapper.Initialize(hwnd);
picker.ViewMode = PickerViewMode.List;
picker.SuggestedStartLocation = PickerLocationId.Desktop;
picker.FileTypeFilter.Add(".txt");
var filesToOpen = await picker.PickMultipleFilesAsync();
string text = string.Empty;
foreach (StorageFile storageFile in filesToOpen)
{
text += storageFile.Path + Environment.NewLine;
}
fileOpenPickerMultipleTextBlock.Text = text;
}
public static void InitializeWithWindow(Object obj, Window window)
{
// When running on win32, FileOpenPicker needs to know the top-level hwnd via IInitializeWithWindow::Initialize.
if (Window.Current == null)
{
IInitializeWithWindow initializeWithWindowWrapper = obj.As<IInitializeWithWindow>();
var hwnd = window.As<IWindowNative>().WindowHandle;
initializeWithWindowWrapper.Initialize(hwnd);
}
}
}
[ComImport]
[Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitializeWithWindow
{
void Initialize([In] IntPtr hwnd);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("EECDBF0E-BAE9-4CB6-A68E-9598E1CB57BB")]
internal interface IWindowNative
{
IntPtr WindowHandle { get; }
} |
Transferring issue to the Project Reunion. It's not a WinUI issue. |
Hey @BenJKuhn, gentle reminder to triage this bug 😊 |
I get a similar error with Any workarounds for now? |
Hi @AmSmart, for PickSingleFolderAsync, are you using |
Yeah, I used the |
I got the same issue on PickMultipleFilesAsync, which crashes WinUI/Reunion WPF desktop app. But PickSingleFolderAsync works well. Do we have workaround or fix now? Thanks in advance. |
FileSavePicker also crashed even use InitializeWithWindow |
PickMultipleFilesAsync is unfortunately not supported right now. You can instead use the Win32 API GetOpenFileName, we're working on posting a workaround sample for that. @Aloento make sure when you're calling |
|
I'd like to share the workaround of using Interop GetOpenFileName API call. By researching several links and verifying some experiments: https://docs.microsoft.com/en-us/windows/win32/dlgbox/open-and-save-as-dialog-boxes I can workaround this issue as below: Notes: This works in Project Reunion 0.8 Preview. If you are using WinUI3 Preview or Project Reunion 0.5, may hit this bug: microsoft/microsoft-ui-xaml#4952 And need to upgrade the project to 0.8 by going through: The helper class is as attached: The calling sample code snippet:
` Hope this helps. |
Just confirming this is not an issue on cppwinrt after
|
The wrong thread exception in the repro app looks to be fixed with the CsWinRT update in .NET SDK 5.0.302. Specifically, the CsWinRT fix for calling non agile objects (microsoft/CsWinRT#844) resolves it. |
Awesome @manodasanW, so can you confirm that PickMultipleFilesAsync is now functional for C# apps if you use .NET SDK 5.0.302 and the IInitializeWithWindow? If so, we can close this thread! |
@castorix Getting error. |
It is another error that some people met from Google |
@castorix No, I am trying with windows 11 |
Maybe try from a new WinUI 3 blank project, then set it Unpackaged, then add code by copy/paste... |
@castorix Can we select multiple folders and multiple files at the same time? |
Yes, with the custom Button added in the Dialog Box (that I named "Return selected items") : |
@castorix Can we remot this button from picker? want to remove open option from file picker |
@castorix Can we change the position to return the selected item button? OnFolderChange where should I call this function? |
I copied-pasted CFileDialog.cs with quick changes to hide Open button and resize the custom button, to be improved : https://pastebin.com/a2Ntn335 |
Yes, I made a last change that I did not test... |
Is it the custom button that you renamed ? |
Yes, if the text is exactly "Select" (without spaces) |
You have set 0, 0 for location in SetWindowPos, instead of |
In the main code : The class : Result : |
@castorix All going perfectly but the files/folder picker is open in full screen. Can we change the size? |
On my OS, Windows 10 22H2, it saves the position/dimensions and it is opened at the latest ones. |
@castorix I am using the Multiple Files and Directories picker, but when I click on the "Select" button, it does not return anything nor dialog close. But when I click the "Cancel" button, it closes the window. I copied your code to another custom page (HomePage.xaml and HomePage.xaml.cs), not in MainWindow, has it caused an issue? When I debugged the code, I found that the selected line in the below screenshot returned nothing when I clicked on the "Select" button, but If I clicked on the "Cancel" button it did return an "E_CANCELLED" output. |
@castorix Yes, it is the same code, as I don't need the bOpen, so I removed that variable. |
@castorix No, it does not go. |
Is m_hWndOwner correct at :
|
Hello @castorix Brother, We have been getting unknown expectations for 7-10 days. I can't share the whole project with you due to the large dependency on a backend server and complexity. So, can we connect on a remote session for 15 min ( Link )? It will save a lot time of and it will be very helpful to us. I hope you can understand our situation. Thanks a lot in advance. |
Describe the bug
The FileOpenPicker in WinUI3 Preview4 Desktop sample solution breaks and closes the application when trying to open multiple items. Exception details below in the last section.
Steps to reproduce the bug
Expected behavior
We expect the application to display the path of the selected file(s) or folder.
We expect the FileOpenPicker to allow the user to select multiple files as it does in UWP.
Screenshots
Screenshot#1a and 1b - Current Behavior (Single File working and Crash Error Message)
Screenshot#2 - Expected Behavior (File paths of selected files)
Version Info
NuGet package version:
[Microsoft.WinUI 3.0.0-preview4.210210.4]
Targeting:
Target: Universal Windows
Target version: Windows 10, version 1809 (10.0; Build 17763)
Min version: Windows 10, version 1803 (10.0; Build 17134)
Windows app type:
Additional context
Exception Details
System.Reflection.TargetInvocationException
HResult=0x80131604
Message=Exception has been thrown by the target of an invocation.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at WinRT.SingleInterfaceOptimizedObject..ctor(Type type, IObjectReference objRef)
at Windows.Storage.Pickers.FilePickerSelectedFilesArray.<.ctor>b__8_1()
at System.Lazy
1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy
1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)at System.Lazy
1.CreateValue() at System.Lazy
1.get_Value()at Windows.Storage.Pickers.FilePickerSelectedFilesArray.AsInternal(InterfaceTag`1 _)
at Windows.Storage.Pickers.FilePickerSelectedFilesArray.GetEnumerator()
at FileOpenPickerWinUIPreview4.MainWindow.<fileOpenPickerMultipleButton_Click>d__2.MoveNext() in \FileOpenPickerWinUIPreview4\FileOpenPickerWinUIPreview4\MainWindow.xaml.cs:line 60
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
COMException: The application called an interface that was marshalled for a different thread. (0x8001010E (RPC_E_WRONG_THREAD))
The text was updated successfully, but these errors were encountered: