WindowsAppSDK
WindowsAppSDK copied to clipboard
Trying to use a FileOpenPicker while running the app as Administrator will crash the app
Describe the bug
I am trying to open a File Picker but it works only if I am not using the app in elevation mode.
I'm getting the following error:
System.Runtime.InteropServices.COMException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'
The error appears when the code tries to execute the following line of code:
var file = await picker.PickSingleFileAsync();
Steps to reproduce the bug
- Create a WASDK app using version 1.4.2 and .NET 7
- Create an extension method so you can get the Window Handle
AppWindowExtension.cs
public static IntPtr GetHandle(this Microsoft.UI.Xaml.Window window)
{
return WinRT.Interop.WindowNative.GetWindowHandle(window);
}
- Make the MainWindow available outside the App class
App.xaml.cs
public static Window MainWindow { get; private set; }
- Use the generated Button_Click event method to open the File Picker
MainWindow.xaml.cs
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
InitializeWithWindow.Initialize(picker, App.MainWindow.GetHandle());
var file = await picker.PickSingleFileAsync();
- Build the app and try to Run as Administrator (it's not neccesary to configure elevation, just right click on the app works)
- Click the button to open the File Picker
- The app will crash :(
Expected behavior
I would expect this basic feature of picking a file to work even if I run the app as admin. My app has a lot of features that require elevation so getting rid of elevation is not an option for me.
Screenshots
No response
NuGet package version
1.4.2
Packaging type
Packaged (MSIX)
Windows version
Insider Build (xxxxx) (only on Windows 11)
IDE
Visual Studio 2022
Additional context
The same for FolderPicker
I can confirm this bug. Any temporary workground for this?
@Petrarca181 yes, you can use directly PInvoke with CsWin32, but it's too much overhead if you ask me.
我在WindowsAppSDK 1.1 Preview 3中使用FolderPicker时遇到了同样的问题,但是我的程序需要提升的权限 I had the same problem using FolderPicker under WindowsAppSDK 1.1 Preview 3, but my program required elevated privileges
@Petrarca181 I had to write my own with P/Invoke as well, It's basic and blocking / non-async, but gets the job done. Mostly copied from here.
using System;
using System.Runtime.InteropServices;
namespace Namespace
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct OpenFileName
{
public int lStructSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpstrFilter;
public string lpstrCustomFilter;
public int nMaxCustFilter;
public int nFilterIndex;
public string lpstrFile;
public int nMaxFile;
public string lpstrFileTitle;
public int nMaxFileTitle;
public string lpstrInitialDir;
public string lpstrTitle;
public int Flags;
public short nFileOffset;
public short nFileExtension;
public string lpstrDefExt;
public IntPtr lCustData;
public IntPtr lpfnHook;
public string lpTemplateName;
public IntPtr pvReserved;
public int dwReserved;
public int flagsEx;
}
public static class FilePicker
{
[DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool GetOpenFileName(ref OpenFileName ofn);
// usage: string filename = FilePicker.ShowDialog("C:\\", new string[] { "png", "jpeg", "jpg" }, "Image Files", "Select an Image File...");
public static string ShowDialog(string startingDirectory, string[] filters, string filterName, string dialogTitle)
{
var ofn = new OpenFileName();
ofn.lStructSize = Marshal.SizeOf(ofn);
ofn.lpstrFilter = filterName;
foreach (string filter in filters)
{
ofn.lpstrFilter += $"\0*.{filter}";
}
ofn.lpstrFile = new string(new char[256]);
ofn.nMaxFile = ofn.lpstrFile.Length;
ofn.lpstrFileTitle = new string(new char[64]);
ofn.nMaxFileTitle = ofn.lpstrFileTitle.Length;
ofn.lpstrTitle = dialogTitle;
if (GetOpenFileName(ref ofn))
return ofn.lpstrFile;
return string.Empty;
}
}
}
Then, you can call it like so:
string filename = FilePicker.ShowDialog("C:\\", new string[] { "png", "jpeg", "jpg" }, "Image Files", "Select an Image File...");
Or, if you must use naitive, you can work around this bug by running the rest of your code as admin, and this not as admin using impersonation.
@manodasanW - crashes right at the PickSingleFileAsync() call.
Yes, the problem still exist in WinUI3 with admin right. Please fix this!
After discussing this with the filesystem team, the recommendation is to use the IFileOpenDialog apis from CSWin32. Here is a recent thread discussing this very topic - FileOpenDialog in CsWin32.
@AdamBraden thank you for oferring this workaround. Any updates related to fixing the issue?
What we could consider is creating a WinAppSDK wrapper around IFileDialog apis that provide an equivalent to the Picker apis. There are some opportunities to improve as well - StorageFiles are very heavyweight objects, and so we could consider returning something more optimized.
@manodasanW, @MikeHillberg, @AdamBraden, hi! Any progress on this? I would appreciate an update. I'm curious how it goes.
https://github.com/OpenKneeboard/OpenKneeboard/blob/e45bbfd46d953a562a9aaa59f38607472d9ea830/src/app/app-winui3/FilePicker.h and https://github.com/OpenKneeboard/OpenKneeboard/blob/e45bbfd46d953a562a9aaa59f38607472d9ea830/src/app/app-winui3/FilePicker.cpp are an example of using the IFileDialog
workaround with modern C++ and cppwinrt
WinUI3 makes me crazy for even basic stuff is not working. I return back to use electron.
Indeed, such a simple thing like a FilePicker requires advanced knowledge and years of experience to understand. I'm a C# developer and I need to use unmanaged code with C++ to open a file picker...this is not how developement experience for WASDK should be.
I just discovered that on Windows 10 it works. The problem is only on Windows 11.
Same problem on windows 10 here.
Same problem on windows 10 here.
what version do you have?
same issue here on Win11
It's been 9 months since the issue was reported, any hopes it will be fixed in WASDK 1.3?
@fredemmott tested again on a clean installation of Windows 10 and no longer works
The workaround is to use IFileDialog. For example:
try
{
PInvoke.CoCreateInstance(
typeof(FileOpenDialog).GUID,
null,
CLSCTX.CLSCTX_INPROC_SERVER,
out IFileDialog fileOpenDialog).ThrowOnFailure();
fileOpenDialog.Show((HWND)App.MainWindow.GetHandle());
fileOpenDialog.GetResult(out IShellItem item);
item.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out PWSTR name);
Console.WriteLine(name.ToString());
Marshal.FreeCoTaskMem(new IntPtr(name.Value));
}
catch (COMException)
{
// Handle canceled.
}
@AdamBraden what if you want to filter the file types? I tried to use IFileDialog but I did not manage to use filters.
You tried SetFilter? https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfilter
@AdamBraden yes, thank you for answering, but I couldn't understand what values to pass as parameters. If you could give me an example, I would really apreciate it. I'm new to unmanaged code.
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfiletypes might be what you want instead
https://github.com/OpenKneeboard/OpenKneeboard/blob/e45bbfd46d953a562a9aaa59f38607472d9ea830/src/app/app-winui3/FilePicker.cpp#L50 is a C++ example; I don't have a C# one.
In short, "name" in the struct is user-visible name (e.g. "Text File"), "pattern" is semicolon-separated globs, e.g. *.txt;*.log
@fredemmott yes, that'a exactly how I tried I just wasn't able to find a fix for all the type errors I got. Those types don't exactly match with C# ones.
You tried SetFilter? https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfilter
Replaced by SetFileTypes (I had posted samples for IFileDialog on MS forums, in C# and VB.NET)
@castorix link please?
@castorix link please?
I found old links... but they cutted the code :-( I will try to re-post, but you can find various implementations by typing for example in Google "IFileOpenDialog comimport github"
@AdamBraden I noticed even WinUI 3 Gallery has the same problem in their FilePicker example - up til now. Running the app as Admin makes the function break. Conclusion: it's a WinUI/SDK bug. When will the actual problem be solved? :)
@AdamBraden I noticed even WinUI 3 Gallery has the same problem in their FilePicker example - up til now. Running the app as Admin makes the function break. Conclusion: it's a WinUI/SDK bug. When will the actual problem be solved? :)
Probably in 2-3 years.