C# 拖放;从Windows便携设备拖放到WPF应用程序

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()中发布了这个问题,但没有得到任何线索 这里有我遗漏的东西吗?你能帮我解决这个问题吗 以

我正在开发一个WPF应用程序,它允许用户从Windows资源管理器拖放文件。对于普通文件,我可以使用
字符串[]文件名=(字符串[])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。但无法使它工作。我应该用别的东西还是我做错了什么?