我正在尝试从另一个Windows应用程序(EM Client,Thunderbird或Outlook)拖到我的表单上。将电子邮件从其他应用程序拖到Windows浏览时,它将作为文件删除。如果用户拖动到我的应用程序上,我希望将文件内容作为文件流获取。
我能够在UWP应用程序中使用它,但是我需要在Windows Form应用程序中使用它,以便它可以在Windows 7中使用。
我发现了很多使用其他方法的示例(从App拖动到Windows)。
在UWP应用程序中,这很烦人。 这是我在UWP应用程序中执行的操作,其结果是我将一个新文件保存在漫游文件夹中,名称为“ email.eml”:
XAML
<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
Background="LightBlue" Margin="10,10,10,353">
<TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>
XAML.CS
namespace App1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Grid_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
}
private async void Grid_Drop(object sender, DragEventArgs e)
{
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.DataView.GetStorageItemsAsync();
if (items.Count > 0)
{
var storageFile = items[0] as StorageFile;
var reader = (await storageFile.OpenAsync(FileAccessMode.Read));
IBuffer result = new byte[reader.Size].AsBuffer();
var test = await reader.ReadAsync(result, result.Length,Windows.Storage.Streams.InputStreamOptions.None);
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync("email.eml",Windows.Storage.CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, test);
}
}
}
}
}
我已经阅读了此答案中列出的每篇文章,以及更多内容: Trying to implement Drag and Drop gmail attachment from chrome
基本上,无论我如何进行攻击,最终我都会得到以下3个结果之一:
这是违反安全性的代码:
MemoryStream ClipboardMemoryStream = new MemoryStream();
BinaryFormatter bft = new BinaryFormatter();
bft.Serialize(ClipboardMemoryStream, e.Data.GetData("FileGroupDescriptorW", false));
byte[] byteArray = ClipboardMemoryStream.ToArray();
我的猜测是我需要实现e.Data.GetData(“ FileGroupDesciptorW”)返回一个IStorage类,并且我需要实现该类,但是我对如何做到这一点迷失了,而且我不是确定是这样
e.Data.GetType显示它的marshalbyrefobject,我尝试手动执行Remoting,但是我陷入了没有开放频道的困境。
https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-istorage https://docs.microsoft.com/en-us/windows/desktop/shell/datascenarios#dragging-and-dropping-shell-objects-asynchronously
答案 0 :(得分:0)
因此,在寻求专业人士的帮助后,我有了一个可行的例子。诀窍是让“ FileDescriptorW”在自定义ComObject类中工作。您可以在从Outlook example拖动中找到该类的版本,但是从EM Client拖动时它不起作用。
代码如下: Code is too Big to post
然后您可以像这样使用它:
MyDataObject obj = new MyDataObject(e.Data);
string[] fileNames = { };
//ThunderBird Does a FileDrop
if (obj.GetDataPresent(DataFormats.FileDrop, true))
{
string[] tempFileNames = (string[])obj.GetData(DataFormats.FileDrop);
List<string> tempFileNameList = new List<string>();
foreach(string f in tempFileNames)
{
tempFileNameList.Add(Path.GetFileName(f));
}
fileNames = tempFileNameList.ToArray();
} else if (fileNames.Length == 0)
{
//EM Client uses "FileGroupDescriptorW"
fileNames = (string[])obj.GetData("FileGroupDescriptorW");
}else if (fileNames.Length == 0)
{
//Outlook Uses "FileGroupDescriptor"
fileNames = (string[])obj.GetData("FileGroupDescriptor");
}
int index = 0;
foreach (string f in fileNames)
{
File.WriteAllBytes("C:\\FilePath\\"+f, obj.GetData("FileContents", index).ToArray());
index++;
}