gpt4 book ai didi

c# - 从另一个应用程序拖放 C# Windows 窗体应用程序

转载 作者:太空宇宙 更新时间:2023-11-03 14:51:16 24 4
gpt4 key购买 nike

我正在尝试从另一个 Windows 应用程序(EM 客户端、雷鸟或 Outlook)拖到我的表单上。当将电子邮件从其他应用程序拖到 Windows Explorer 时,它将作为文件放置。如果用户拖到我的应用程序上,我希望将文件内容作为文件流获取。

我能够在 UWP 应用程序中使用它,但我需要在 Windows 窗体应用程序中使用它,这样它才能在 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 个结果之一:

  1. “无效的 FORMATETC 结构(来自 HRESULT 的异常:0x80040064(DV_E_FORMATETC))”的异常
  2. 我的 MemoryStream 为空
  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,我试图手动执行远程处理,但我卡在没有开放 channel 上。

https://learn.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-istorage https://learn.microsoft.com/en-us/windows/desktop/shell/datascenarios#dragging-and-dropping-shell-objects-asynchronously

最佳答案

所以在向专业人士寻求帮助后,我有了一个可行的例子。诀窍是让“FileDescriptorW”在 Custom 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++;
}

关于c# - 从另一个应用程序拖放 C# Windows 窗体应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51679318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com