C# 将Outlook拖放到Winforms中

C# 将Outlook拖放到Winforms中,c#,winforms,outlook,drag-and-drop,idataobject,C#,Winforms,Outlook,Drag And Drop,Idataobject,将项目从Outlook电子邮件拖动到Winforms应用程序中时(控件是由DevExpress创建的GalleryControl),DragDrop事件不会触发,即使我在DragEnter事件处理程序中手动设置了“DragDropEffects.Move”。(已确认此事件正在触发) 但是,DragDrop事件仅在从windows资源管理器拖动普通文件时才会触发 private async void gcImages_DragDrop(object sender, DragEventArg

将项目从Outlook电子邮件拖动到Winforms应用程序中时(控件是由DevExpress创建的
GalleryControl
),DragDrop事件不会触发,即使我在DragEnter事件处理程序中手动设置了“DragDropEffects.Move”。(已确认此事件正在触发)

但是,DragDrop事件仅在从windows资源管理器拖动普通文件时才会触发

    private async void gcImages_DragDrop(object sender, DragEventArgs e)
    {

        string[] fileNames = null;

        if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
        {
            fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
        }
        else if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            OutlookDataObject dataObject = new OutlookDataObject(e.Data);
            string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
        }
        // do stuff async with file names
    }

    private void gcImages_DragEnter(object sender, DragEventArgs e)
    {
        // This event fires, no matter what i drag onto it.  (Files from explorer, attachments from Outlook etc)  
        // However even after setting the effect as per below, the cursor still shows the 'not allowed' symbol.
        e.Effect = DragDropEffects.Move;
    }
我在控件上启用了
AllowDrop=true
,它可以完美地处理Windows资源管理器文件,而不是outlook文件


奇怪的是DragEnter事件正在启动,但DragDrop事件不会与Outlook附件一起启动。

最终使用了此代码,似乎工作正常

//// Use Like This

    private void gcImages_DragDrop(object sender, DragEventArgs e)
    {
        DragDropHelper.AcceptDroppedFile(e, AddAndSaveNewDocument);
    }

    private void AddAndSaveNewDocument(FileSystemInfo fileInfo)
    {

    }


////


public static class DragDropHelper
{
    public static void AcceptDroppedFile(DragEventArgs e, Action<FileInfo> addAndSaveNewDocument)
    {
        string[] fileNames = null;

        if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
        {
            fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
        }
        else if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            var dataObject = new OutlookDataObject(e.Data);
            fileNames = (string[])dataObject.GetData("FileGroupDescriptor");

            for (var i = 0; i < fileNames.Length; i++)
            {
                var itm = fileNames[i];
                using var ms = dataObject.GetData("FileContents", i);

                var tmpFileName = Path.Combine(Path.GetTempPath(), itm);

                using (var file = new FileStream(tmpFileName, FileMode.Create, System.IO.FileAccess.Write))
                {
                    byte[] bytes = new byte[ms.Length];
                    ms.Read(bytes, 0, (int)ms.Length);
                    file.Write(bytes, 0, bytes.Length);
                    ms.Close();
                }

                fileNames[i] = tmpFileName;
            }
        }
        if (fileNames != null)
        {
            foreach (var fileName in fileNames)
            {
                var fileInfo = new FileInfo(fileName);

                addAndSaveNewDocument(fileInfo);

                if (fileName.Contains(Path.GetTempPath(), StringComparison.CurrentCultureIgnoreCase))
                {
                    File.Delete(fileName);
                }
            }
        }
    }
}
///像这样使用
私有void gcImages_DragDrop(对象发送方,DragEventArgs e)
{
DragDropHelper.AcceptDroppedFile(e、AddAndSaveNewDocument);
}
私有void AddAndSaveNewDocument(FileSystemInfo fileInfo)
{
}
////
公共静态类DragDropHelper
{
公共静态void AcceptDroppedFile(DragEventArgs e、Action add和SaveNewDocument)
{
字符串[]文件名=null;
if(例如Data.GetDataPresent(DataFormats.FileDrop,false))
{
fileNames=(字符串[])e.Data.GetData(DataFormats.FileDrop);
}
else if(例如Data.GetDataPresent(“FileGroupDescriptor”))
{
var dataObject=新的OutlookDataObject(即数据);
fileNames=(字符串[])dataObject.GetData(“FileGroupDescriptor”);
对于(var i=0;i

这里用于OutlookDataObjectclass

的代码最终使用了这段代码,似乎工作正常

//// Use Like This

    private void gcImages_DragDrop(object sender, DragEventArgs e)
    {
        DragDropHelper.AcceptDroppedFile(e, AddAndSaveNewDocument);
    }

    private void AddAndSaveNewDocument(FileSystemInfo fileInfo)
    {

    }


////


public static class DragDropHelper
{
    public static void AcceptDroppedFile(DragEventArgs e, Action<FileInfo> addAndSaveNewDocument)
    {
        string[] fileNames = null;

        if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
        {
            fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
        }
        else if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            var dataObject = new OutlookDataObject(e.Data);
            fileNames = (string[])dataObject.GetData("FileGroupDescriptor");

            for (var i = 0; i < fileNames.Length; i++)
            {
                var itm = fileNames[i];
                using var ms = dataObject.GetData("FileContents", i);

                var tmpFileName = Path.Combine(Path.GetTempPath(), itm);

                using (var file = new FileStream(tmpFileName, FileMode.Create, System.IO.FileAccess.Write))
                {
                    byte[] bytes = new byte[ms.Length];
                    ms.Read(bytes, 0, (int)ms.Length);
                    file.Write(bytes, 0, bytes.Length);
                    ms.Close();
                }

                fileNames[i] = tmpFileName;
            }
        }
        if (fileNames != null)
        {
            foreach (var fileName in fileNames)
            {
                var fileInfo = new FileInfo(fileName);

                addAndSaveNewDocument(fileInfo);

                if (fileName.Contains(Path.GetTempPath(), StringComparison.CurrentCultureIgnoreCase))
                {
                    File.Delete(fileName);
                }
            }
        }
    }
}
///像这样使用
私有void gcImages_DragDrop(对象发送方,DragEventArgs e)
{
DragDropHelper.AcceptDroppedFile(e、AddAndSaveNewDocument);
}
私有void AddAndSaveNewDocument(FileSystemInfo fileInfo)
{
}
////
公共静态类DragDropHelper
{
公共静态void AcceptDroppedFile(DragEventArgs e、Action add和SaveNewDocument)
{
字符串[]文件名=null;
if(例如Data.GetDataPresent(DataFormats.FileDrop,false))
{
fileNames=(字符串[])e.Data.GetData(DataFormats.FileDrop);
}
else if(例如Data.GetDataPresent(“FileGroupDescriptor”))
{
var dataObject=新的OutlookDataObject(即数据);
fileNames=(字符串[])dataObject.GetData(“FileGroupDescriptor”);
对于(var i=0;i

这里的代码用于OutlookDataObjectclass

您可能会遇到以下限制,即较低权限的进程无法拖放到较高权限的应用程序。无法使用不同类型的用户进行复制(Outlook 2016/x64)。该对象包含一个
FILEDESCRIPTORW
结构数组。MemoryStream的第一个字节包含结构数。结构返回附件的文件名,而
FileContents
格式返回包含附件字节的MemoryStream。在标准WinForms控件上拖放笔。尝试使用具有不同用户权限的非DevXpress控件,以测试在您的上下文中什么是有效的。为了让它与Outlook 2019一起工作,您使用的是2013吗?知道为什么吗?您可能遇到了一个限制,即低权限进程无法拖放到高权限应用程序。无法使用不同的t用户类型(Outlook 2016/x64)。该对象包含一个
FILEDESCRIPTORW
结构数组。MemoryStream的第一个字节包含结构数。结构返回附件的文件名,而
FileContents
格式返回包含附件字节的MemoryStream。在标准WinForms控件上拖放笔。尝试使用非DevExpress控件,使用不同的用户权限