C# 拖放;从Windows便携设备拖放到WPF应用程序
我正在开发一个WPF应用程序,它允许用户从Windows资源管理器拖放文件。对于普通文件,我可以使用C# 拖放;从Windows便携设备拖放到WPF应用程序,c#,wpf,drag-and-drop,wpd,C#,Wpf,Drag And Drop,Wpd,我正在开发一个WPF应用程序,它允许用户从Windows资源管理器拖放文件。对于普通文件,我可以使用 字符串[]文件名=(字符串[])e.Data.GetData(DataFormats.FileDrop,false) 但是对于WPD文件,它返回null。我曾试图遵循中给出的解决方案,但无法使其工作。我在尝试从Shell数组获取项目计数时遇到AccessVoilationException。我已经在MSDN()中发布了这个问题,但没有得到任何线索 这里有我遗漏的东西吗?你能帮我解决这个问题吗 以
字符串[]文件名=(字符串[])e.Data.GetData(DataFormats.FileDrop,false) 但是对于WPD文件,它返回null。我曾试图遵循中给出的解决方案,但无法使其工作。我在尝试从Shell数组获取项目计数时遇到AccessVoilationException。我已经在MSDN()中发布了这个问题,但没有得到任何线索 这里有我遗漏的东西吗?你能帮我解决这个问题吗 以下是我的代码的相关部分
public enum SIGDN : uint
{
NORMALDISPLAY = 0,
PARENTRELATIVEPARSING = 0x80018001,
PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
DESKTOPABSOLUTEPARSING = 0x80028000,
PARENTRELATIVEEDITING = 0x80031001,
DESKTOPABSOLUTEEDITING = 0x8004c000,
FILESYSPATH = 0x80058000,
URL = 0x80068000
}
internal class IIDGuid
{
private IIDGuid() { } // Avoid FxCop violation AvoidUninstantiatedInternalClasses
// IID GUID strings for relevant COM interfaces
internal const string IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
internal const string IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8";
internal const string IFileOpenDialog = "d57c7288-d4ad-4768-be02-9d969532d960";
internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab";
internal const string IFileDialogEvents = "973510DB-7D7F-452B-8975-74A85828D354";
internal const string IShellItem = "43826D1E-E718-42EE-BC55-A1E261C37BFE";
internal const string IShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B";
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
public interface IShellItem
{
void BindToHandler(IntPtr pbc,
[MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
[MarshalAs(UnmanagedType.LPStruct)]Guid riid,
out IntPtr ppv);
void GetParent(out IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
void Compare(IShellItem psi, uint hint, out int piOrder);
};
[ComImport]
[Guid(IIDGuid.IShellItemArray)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IShellItemArray
{
// Not supported: IBindCtx
void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, out IntPtr ppvOut);
void GetPropertyStore([In] int Flags, [In] ref Guid riid, out IntPtr ppv);
void GetCount(out uint pdwNumItems);
void GetItemAt([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
void EnumItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenumShellItems);
}
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int SHCreateShellItemArrayFromDataObject(
System.Runtime.InteropServices.ComTypes.IDataObject pdo,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppv);
[DllImport("kernel32.dll", SetLastError = true)]
static extern Int32 GetLastError();
private void OnFileDrop(object sender, DragEventArgs e)
{
string[] fileNames = (string[])e.Data.GetData(DataFormats.FileDrop, false);// null
System.Runtime.InteropServices.ComTypes.IDataObject mydata = e.Data as System.Runtime.InteropServices.ComTypes.IDataObject;
IShellItemArray nativeShellItemArray;
Guid guid = new Guid(IIDGuid.IShellItemArray);
int retCode = SHCreateShellItemArrayFromDataObject(mydata, ref guid, out nativeShellItemArray);
IShellItem nativeShellItem;
if (retCode == 0)
{
IntPtr displayname;
uint items = 0;
try
{
nativeShellItemArray.GetCount(out items); //Getting AccessVoilationException in this line
}
catch (Exception ex)
{
}
if (items > 0)
{
for (uint item = 0; item < items; item++)
{
nativeShellItemArray.GetItemAt(item, out nativeShellItem);
nativeShellItem.GetDisplayName(SIGDN.DESKTOPABSOLUTEPARSING, out displayname);
//Do something
}
}
}
}
公共枚举SIGDN:uint
{
NORMALDISPLAY=0,
PARENTRELATIVEPARSING=0x80018001,
PARENTRELATIVEFORADDRESSBAR=0x8001c001,
DESKTOPABSOLUTEPARSING=0x80028000,
PARENTRELATIVEEDITING=0x80031001,
DESKTOPABSOLUTEEDITING=0x8004c000,
FILESYSPATH=0x80058000,
URL=0x80068000
}
内部类IIDGuid
{
private IIDGuid(){}//避免FxCop冲突AvoidUninstatiatedInternalClass
//相关COM接口的IID GUID字符串
内部常量字符串IModalWindow=“b4db1657-70d7-485e-8e3e-6fcb5a5c1802”;
内部常量字符串IFileDialog=“42f85136-db7e-439c-85f1-e4075d135fc8”;
内部常量字符串IFileOpenDialog=“d57c7288-d4ad-4768-be02-9d969532d960”;
内部常量字符串IFileSaveDialog=“84bccd23-5fde-4cdb-aea4-af64b83d78ab”;
内部常量字符串IFileDialogEvents=“973510DB-7D7F-452B-8975-74A85828D354”;
内部常量字符串IShellItem=“43826D1E-E718-42EE-BC55-A1E261C37BFE”;
内部常量字符串IShellItemArray=“B63EA76D-1F85-456F-A19C-48159EFA858B”;
}
[ComImport]
[接口类型(ComInterfaceType.InterfaceSiunknown)]
[Guid(“43826d1e-e718-42ee-bc55-a1e261c37bfe”)]
公共接口IShellItem
{
无效BindToHandler(IntPtr pbc,
[Marshallas(UnmanagedType.LPStruct)]Guid bhid,
[Marshallas(UnmanagedType.LPStruct)]Guid riid,
输出IntPtr ppv);
无效GetParent(超出IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName,out IntPtr ppszName);
void GetAttributes(uint SFGAOSMASK、out uint psfgaoAttribs);
无效比较(IShellItem psi、uint提示、out int piOrder);
};
[ComImport]
[Guid(IIDGuid.IShellItemArray)]
[接口类型(ComInterfaceType.InterfaceSiunknown)]
内部接口阵列
{
//不支持:IBindCtx
void BindToHandler([In,marshallas(UnmanagedType.Interface)]IntPtr pbc,[In]ref Guid rbhid,[In]ref Guid riid,out IntPtr ppvOut);
void GetPropertyStore([In]int Flags,[In]ref Guid riid,out IntPtr ppv);
void GetCount(out uint pdwNumItems);
void GetItemAt([In]uint-dwIndex[marshallas(UnmanagedType.Interface)]out-IShellItem-ppsi);
void EnumItems([Marshallas(UnmanagedType.Interface)]out IntPtr ppenumShellItems);
}
[DllImport(“shell32.dll”,CharSet=CharSet.Unicode,SetLastError=true)]
静态外部int SHCreateShellItemArrayFromDataObject(
System.Runtime.InteropServices.ComTypes.IDataObject pdo,
参考Guid riid,
[Marshallas(UnmanagedType.Interface)]输出IShellItemArray ppv;
[DllImport(“kernel32.dll”,SetLastError=true)]
静态外部程序Int32 GetLastError();
私有void OnFileDrop(对象发送方,DragEventArgs e)
{
string[]fileNames=(string[])e.Data.GetData(DataFormats.FileDrop,false);//null
System.Runtime.InteropServices.ComTypes.IDataObject mydata=e.数据为System.Runtime.InteropServices.ComTypes.IDataObject;
IShellItemArray nativeShellItemArray;
Guid=新Guid(IIDGuid.IShellItemArray);
int retCode=SHCreateShellItemArrayFromDataObject(mydata,ref guid,out nativeShellItemArray);
IShellItem nativeShellItem;
如果(retCode==0)
{
IntPtr显示名;
uint项目=0;
尝试
{
nativeShellItemArray.GetCount(out items);//获取此行中的AccessVoilationException
}
捕获(例外情况除外)
{
}
如果(项目>0)
{
对于(uint item=0;item
什么是e.Data.GetFormats()
返回的?我认为您不应该使用FileDrop格式,因为WPD上的项目没有路径…@thomasleveque我发现了这一点,这就是为什么我尝试使用ShellItemArray。但无法使它工作。我应该用别的东西还是我做错了什么?