我们在WPF应用程序(针对.NET Framework 4.7.2(中使用Microsoft.Win32.OpenFileDialog
时遇到问题。
我们希望能够通过USB连接从连接到计算机的智能手机导入多个文件。然而,使用OpenFileDialog
似乎不可能做到这一点,因为它会触发消息框"em";无法从此位置打开多个项目。请尝试选择单个项目"。你可以使用这个简单的代码复制它,并从你的智能手机中选择至少2张图片:
var openFileDialog = new Microsoft.Win32.OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.ShowDialog();
这个问题是已知的(参见此处和此处(,并且与MTP协议有关。该问题不会在使用替代方案"连接"的智能手机的情况下发生;USB Mas存储器";(UMS(,但这一选项在现代智能手机上不可用。
UWPFileOpenPicker
似乎可以更好地处理多个项目的选择(请参阅此处了解如何在WPF应用程序中使用它(,但我们在使用PickMultipleFilesAsync
时会考虑InvalidCastException
。这里描述了这个问题,答案表明FileOpenPicker
不能在WPF中使用。NET Framework应用程序。
正如评论中所说,实现这一点的另一种方法是使用智能手机设备的MTP协议实现skratch的文件选择器。这种方法的缺点是。NET和UWP文件拾取器提供了许多出色的功能,并与操作系统完全集成。
我们已经没有办法解决这个问题了,所以我的问题是:
是否有一种方法可以在WPF应用程序目标中使用Windows文件选择器从智能手机导入多个文件。NET框架
同样的问题也被问到微软的问答;A.
我回复有点晚了,但多亏了微软的问答,我找到了解决方案;一根线。
据我所知,使用Microsoft.Win32.OpenFileDialog
无法从MTP设备中选择多个文件,因为您无法设置所有IFileOpenDialog
选项。
因此,您需要使用自己的IFileOpenDialog
来设置选项:确保添加FOS_ALLOWMULTISELECT
选项并删除FOS_FORCEFILESYSTEM
:
ComFileDialog.IFileOpenDialog fileOpenDialog = null;
ComFileDialog.IShellItemArray shellItemArray = null;
ComFileDialog.IShellItem shellItem = null;
try
{
// Set options
fileOpenDialog = (ComFileDialog.IFileOpenDialog)new ComFileDialog.FileOpenDialogRCW();
fileOpenDialog.GetOptions(out var options);
options |= ComFileDialog.FOS_ALLOWMULTISELECT | ComFileDialog.FOS_FILEMUSTEXIST | ComFileDialog.FOS_PATHMUSTEXIST;
fileOpenDialog.SetOptions(options);
// Show window
if (fileOpenDialog.Show() != ComFileDialog.S_OK)
{
return;
}
// Get results
if (fileOpenDialog.GetResults(out shellItemArray) != ComFileDialog.S_OK)
{
return;
}
uint items = 0;
if (shellItemArray.GetCount(out items) != ComFileDialog.S_OK)
{
return;
}
// Result loop
for (uint item = 0; item < items; item++)
{
try
{
if (shellItemArray.GetItemAt(item, out shellItem) != ComFileDialog.S_OK)
{
continue;
}
// Use the IShellItem
}
finally
{
if (shellItem != null)
{
Marshal.ReleaseComObject(shellItem);
shellItem = null;
}
}
}
}
finally
{
if (fileOpenDialog != null)
{
Marshal.ReleaseComObject(fileOpenDialog);
}
if (shellItemArray != null)
{
Marshal.ReleaseComObject(shellItemArray);
}
if (shellItem != null)
{
Marshal.ReleaseComObject(shellItem);
}
}
您可以在pinvoke.net上找到WindowShell API接口:
- https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifiledialog
- https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifileopendialog
- http://pinvoke.net/default.aspx/Interfaces/IFileOpenDialog.html
- https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ishellitem
- http://pinvoke.net/default.aspx/Interfaces/IShellItem.html
- https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ishellitemarray
- http://pinvoke.net/default.aspx/Interfaces/IShellItemArray.html
- http://www.pinvoke.net/default.aspx/Interfaces/FileOpenDialogRCW.html