LMS*_*LMS 3 .net c# outlook drag-and-drop winforms
有人有任何 C# 代码可以接受从 Outlook 拖放到在.Net Framework 4.5或更高版本下工作的 Winforms 应用程序吗?
我有一些代码已经使用了大约 12 年,其中包括拖放项目的功能,包括来自 Outlook 的电子邮件。
当将目标框架设置为.Net Framework 4进行编译时,代码可以完美运行,但是我一直在开发的一些新功能需要.Net Framework 4.5或更高版本。但是,这会阻止从 Outlook 进行拖放操作。
代码非常复杂,它做了很多与问题无关的事情来确定文件的去向,以及它为谁显示等,所以我不会包括所有这些,但它中断的点很好并且简单的...
public string ImportEmail(DragEventArgs e)
{
string strResult = string.Empty;
var dataObject = new OutlookDataObject(e.Data);
var filenames = (string[]) dataObject.GetData("FileGroupDescriptor");
Run Code Online (Sandbox Code Playgroud)
在.NET 4下,上面的最后一行按预期返回文件名。
在.NET 4.5 或更高版本中,上面的最后一行返回null。
我在.NET 4.5、4.5.1、4.5.2、4.6、4.6.1、4.6.2和4.7.2(我安装的所有版本)下测试了它,它不适用于其中任何一个。
我已经花了几天时间尝试所有我能找到的拖放代码,但似乎都无法在 .Net 4.5 或更高版本下工作。
下面是我所做的测试表单的完整代码,使用了我从这里和其他地方挖掘的代码。无论您从 Outlook 拖放文件还是电子邮件,此代码都可以在 .Net Framework 4 下完美运行,但在 .Net Framework 4.5 或更高版本下都不起作用(再次测试所有相同版本)。
using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
namespace OutlookDragNDropTest
{
public partial class OutlookDragNDropTest : Form
{
public OutlookDragNDropTest()
{
InitializeComponent();
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
// or this tells us if it is an Outlook attachment drop
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
e.Effect = DragDropEffects.Copy;
}
// or none of the above
else
{
e.Effect = DragDropEffects.None;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
try
{
//wrap standard IDataObject in OutlookDataObject
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
//get the names and data streams of the files dropped
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
MemoryStream[] filestreams = (MemoryStream[])dataObject.GetData("FileContents");
string tempPath = Path.GetTempPath();
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
//use the fileindex to get the name and data stream
string filename = tempPath + filenames[fileIndex];
MemoryStream filestream = filestreams[fileIndex];
//save the file stream using its name to the application path
FileStream outputStream = File.Create(filename);
filestream.WriteTo(outputStream);
outputStream.Close();
MessageBox.Show("Output to " + filename);
}
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.ToString());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
(好吧,对于一篇文章来说代码似乎太长了,OutlookDataObject 类将在下面的回复中)...
唯一的另一件事是表单本身,它只是一个空白的 Winforms 表单,设置了以下属性:-
允许丢弃:真
DragEnter 事件:Form1_DragEnter
拖放事件:Form1_DragDrop
如果相关的话,我使用的是 Visual Studio 2017 Professional,并在 Windows 10 上运行,尽管运行 Windows 7 的客户端也报告了拖放不起作用。
解决了!
事实证明,问题是 .Net Framework 4 及更低版本使用32 位指针,而 .Net Framework 4.5 及更高版本使用64 位指针。
我拥有的古老代码和我提供的示例代码都是基于指针仅为 32 位的假设编写的。
更改OutlookDataObject类中的以下两行(并在我的代码中进行类似的更改)修复了它:-
从:-
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
Run Code Online (Sandbox Code Playgroud)
到:-
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
Run Code Online (Sandbox Code Playgroud)
不知道为什么我的 Visual Studio 在碰到这些线时没有发出晃动的声音,但是哦,好吧。
通过上述更改,我提供的示例代码可以同时处理文件和 Outlook 电子邮件(单个项目和多个项目)的拖放
归档时间: |
|
查看次数: |
4194 次 |
最近记录: |