Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以编程方式保存outlook电子邮件附件(例如PDF),该附件已由用户使用CTRL-C在C中复制到剪贴板#_C#_Wpf_Outlook_Clipboard - Fatal编程技术网

C# 如何以编程方式保存outlook电子邮件附件(例如PDF),该附件已由用户使用CTRL-C在C中复制到剪贴板#

C# 如何以编程方式保存outlook电子邮件附件(例如PDF),该附件已由用户使用CTRL-C在C中复制到剪贴板#,c#,wpf,outlook,clipboard,C#,Wpf,Outlook,Clipboard,背景: 当复制到剪贴板的文件是桌面上的文件时,我可以通过编程方式复制(使用CTRL-C)和粘贴剪贴板上的文件。使用以下语法,这非常简单: File.Copy(Clipboard.GetFileDropList()[0], savePath) 其中Clipboard.GetFileDropList()[0]返回复制文件的路径,而savePath是粘贴位置 但是,如果复制的文件(使用CTRL-C)是Outlook电子邮件中的文件附件,我发现上述语法不起作用。在这种情况下,Clipboard.Con

背景:

当复制到剪贴板的文件是桌面上的文件时,我可以通过编程方式复制(使用CTRL-C)和粘贴剪贴板上的文件。使用以下语法,这非常简单:

File.Copy(Clipboard.GetFileDropList()[0], savePath)
其中Clipboard.GetFileDropList()[0]返回复制文件的路径,而savePath是粘贴位置

但是,如果复制的文件(使用CTRL-C)是Outlook电子邮件中的文件附件,我发现上述语法不起作用。在这种情况下,Clipboard.ContainsFileDropList()返回false,Clipboard.GetFileDropList()[0]会导致以下错误消息:

“ArgumentOutOfRangeException:索引超出范围。必须为非负且小于集合的大小。参数名称:索引”

尽管按CTRL-V键确实成功粘贴了文件,确认文件最初已成功复制到剪贴板,但仍然存在这种情况

问题:

对不起,如果我错过了一些非常基本的东西。我的问题是,在Outlook中使用CTRL-C将电子邮件附件复制到剪贴板时,如何以编程方式将电子邮件附件(PDF、Word等)从剪贴板粘贴/保存到文件位置


请注意,我确实理解,通过跳过剪贴板并以编程方式与Outlook交互以访问选定的电子邮件附件,可以解决我尝试执行的操作。但是,我的目标是学习如何在不同的场景下以编程方式与剪贴板交互。

您使用了错误的
数据格式。通过调用剪贴板.GetDataObject().GetFormats()
,始终可以获得当前数据格式的列表

您需要使用:

“FileGroupDescriptor”
检索文件名 将附加文件保存到磁盘 由于Windows仅将第一个选定的附件添加到系统剪贴板,因此此解决方案只能保存一个附件。显然,无法访问office剪贴板

private static async Task SaveAttachmentFromClipboardToFileAsync(IDataObject clipboardData, string destinationFilePath)
{
  if (!clipboardData.GetDataPresent("FileContents"))
  {
    return;
  }

  using (var attachedFileStream = clipboardData.GetData("FileContents", true) as MemoryStream)
  {
    using (var destinationFileStream = File.Open(destinationFilePath, FileMode.OpenOrCreate))
    {
      await attachedFileStream.CopyToAsync(destinationFileStream);
    }
  }
}
使用Office API将附加文件保存到磁盘 需要引用Microsoft.Office.Interop.Outlook.dll。此解决方案不依赖于系统剪贴板。它只是从Outlook资源管理器中当前打开的邮件项目中重新加载选定的附件。
您仍然可以监视系统剪贴板以触发保存附件的过程

private static void SaveSelectedAttachementsToFolder(string destinationFolderPath)
{
  var outlookApplication = new Microsoft.Office.Interop.Outlook.Application();
  Explorer activeOutlookExplorer = outlookApplication.ActiveExplorer();
  AttachmentSelection selectedAttachments = activeOutlookExplorer.AttachmentSelection;

  foreach(Attachment attachment in selectedAttachments)
  {
    attachment.SaveAsFile(Path.Combine(destinationFolderPath, attachment.FileName));
  }
}

谢谢@Michael Randall指出这个问题,尽管我不确定我应该从中吸取什么。如果我可以尝试重新表述我的问题:当用户在outlook电子邮件附件上按CTRL-C键时,哪些信息会发送到剪贴板,以及如何以编程方式访问这些信息,考虑到特定的CTRL-C事件似乎不会将clipboard.GetFileDropList切换到“true”状态。根据我做的快速测试,按“复制”时,至少不能对outlook文件使用
GetFileDropList
。您可以使用示例中的代码获得文件和数据列表。这太棒了!谢谢你-这里有很多东西需要我消化-真的很感激。我很高兴能帮上忙。如果你有任何问题,请告诉我。
private static async Task SaveAttachmentFromClipboardToFileAsync(IDataObject clipboardData, string destinationFilePath)
{
  if (!clipboardData.GetDataPresent("FileContents"))
  {
    return;
  }

  using (var attachedFileStream = clipboardData.GetData("FileContents", true) as MemoryStream)
  {
    using (var destinationFileStream = File.Open(destinationFilePath, FileMode.OpenOrCreate))
    {
      await attachedFileStream.CopyToAsync(destinationFileStream);
    }
  }
}
private static void SaveSelectedAttachementsToFolder(string destinationFolderPath)
{
  var outlookApplication = new Microsoft.Office.Interop.Outlook.Application();
  Explorer activeOutlookExplorer = outlookApplication.ActiveExplorer();
  AttachmentSelection selectedAttachments = activeOutlookExplorer.AttachmentSelection;

  foreach(Attachment attachment in selectedAttachments)
  {
    attachment.SaveAsFile(Path.Combine(destinationFolderPath, attachment.FileName));
  }
}