You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从Outlook直接粘贴附件到VB.NET应用的技术问询

VB.NET实现Outlook附件粘贴功能的解决方案

我的VB.NET应用中有一个按钮功能,可将用户剪贴板中的文档粘贴到列表中,但尝试直接复制粘贴Outlook附件时,应用提示“剪贴板中未检测到文件”,然而这些文件却可以正常粘贴到任意文件资源管理器中。请问是否可以通过代码实现Outlook附件的粘贴功能?

原功能代码

Private Sub btnPegar_Click(sender As Object, e As EventArgs) Handles btnPegar.Click
    ' 获取剪贴板数据
    If Clipboard.ContainsData(DataFormats.FileDrop) Then

        Dim fileDropList As String() = CType(Clipboard.GetData(DataFormats.FileDrop), String())

        ' 标记是否找到至少一个有效文件
        Dim archivoValidoEncontrado As Boolean = False

        ' 遍历文件列表并处理每个文件
        For Each filePath As String In fileDropList

            ' 获取文件扩展名
            Dim extensionActual As String = Path.GetExtension(filePath)

            ' 检查文件扩展名是否在允许范围内
            If extensionActual.Equals(".PDF", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".TIF", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".JPG", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".DOC", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".DOCX", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".XLS", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".XLSX", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".BMP", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".PNG", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".GIF", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".DOCUMSG", StringComparison.OrdinalIgnoreCase) OrElse
               extensionActual.Equals(".MSG", StringComparison.OrdinalIgnoreCase) Then

                ' 文件扩展名符合要求
                archivoValidoEncontrado = True

                Try
                    ' 检查文件是否已添加过
                    If archivosAgregados.Contains(filePath) Then                        
                        MessageBox.Show($"文件 '{Path.GetFileName(filePath)}' 已添加过。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Else
                        ' 将文件添加到已添加列表
                        archivosAgregados.Add(filePath)

                        ' 获取文件信息
                        Dim fileInfo As New System.IO.FileInfo(filePath)

                        ' 计算文件大小(KB)
                        Dim fileSizeBytes As Long = fileInfo.Length
                        Dim fileSizeKB As Double = fileSizeBytes / 1024
                        Dim roundedFileSizeKB As Double = Math.Round(fileSizeKB, 2)

                        ' 将文件信息添加到ListView
                        Dim LI As ListViewItem = Me.lstFiles.Items.Add(filePath)
                        LI.StateImageIndex = 0
                        LI.SubItems.Add(roundedFileSizeKB.ToString() & " KB")
                    End If
                Catch ex As Exception
                    MessageBox.Show($"检查文件 '{Path.GetFileName(filePath)}' 时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try
            End If
        Next

        ' 根据列表是否有文件启用/禁用按钮
        If lstFiles.Items.Count > 0 Then
            bProcesar.Enabled = True
            bEliminar.Enabled = True
        Else
            bProcesar.Enabled = False
            bEliminar.Enabled = False
        End If

        ' 所有文件扩展名都不符合要求
        If Not archivoValidoEncontrado Then
            MsgBox("剪贴板中的文件扩展名不被允许。")
        End If
    Else
        ' 剪贴板中没有文件
        MsgBox("剪贴板中不包含文件。")
    End If
End Sub

修改后代码(支持Outlook附件粘贴)

Private Async Sub btnPegar_Click(sender As Object, e As EventArgs) Handles btnPegar.Click
    ' 检查剪贴板是否包含文件数据
    If Clipboard.ContainsData("FileGroupDescriptor") Then
        ' 获取剪贴板中Outlook附件的文件名
        Dim attachedFileNames As List(Of String) = Await GetAttachedFileNamesFromClipboardAsync(Clipboard.GetDataObject())

        ' 标记是否找到至少一个有效文件
        Dim archivoValidoEncontrado As Boolean = False

        ' 遍历附件文件名列表
        For Each fileName As String In attachedFileNames
            ' 检查文件扩展名是否在允许范围内
            Dim extensionActual As String = Path.GetExtension(fileName)

            If extensionActual.Equals(".PDF", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".TIF", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".JPG", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".DOC", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".DOCX", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".XLS", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".XLSX", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".BMP", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".PNG", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".GIF", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".DOCUMSG", StringComparison.OrdinalIgnoreCase) OrElse
           extensionActual.Equals(".MSG", StringComparison.OrdinalIgnoreCase) Then

                ' 文件扩展名符合要求
                archivoValidoEncontrado = True

                Try
                    Dim tempFilePath As String = Path.Combine(Path.GetTempPath(), fileName)
                    Await SaveAttachmentFromClipboardToFileAsync(Clipboard.GetDataObject(), tempFilePath)

                    ' 检查文件是否已添加过
                    If lstFiles.Items.Cast(Of ListViewItem)().Any(Function(item) item.Text = fileName) Then
                        ' 显示提示信息
                        MessageBox.Show($"文件 '{Path.GetFileName(fileName)}' 已添加过。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Else
                        ' 将文件添加到列表
                        Dim LI As ListViewItem = Me.lstFiles.Items.Add(fileName)
                        LI.StateImageIndex = 0

                        ' 获取文件大小并添加到列表
                        Dim fileSizeBytes As Long = New FileInfo(tempFilePath).Length
                        Dim fileSizeKB As Double = fileSizeBytes / 1024
                        Dim roundedFileSizeKB As Double = Math.Round(fileSizeKB, 2)
                        LI.SubItems.Add($"{roundedFileSizeKB} KB")

                        ' 将文件名添加到已添加列表
                        archivosAgregados.Add(fileName)
                    End If
                Catch ex As System.Exception
                    ' 处理异常
                    MessageBox.Show($"检查文件 '{Path.GetFileName(fileName)}' 时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try
            End If
        Next

        ' 根据列表是否有文件启用/禁用按钮
        If lstFiles.Items.Count > 0 Then
            bProcesar.Enabled = True
            bEliminar.Enabled = True
        Else
            bProcesar.Enabled = False
            bEliminar.Enabled = False
        End If

        If Not archivoValidoEncontrado Then
            MessageBox.Show("剪贴板中的文件扩展名不被允许。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End If
    Else
        MessageBox.Show("剪贴板中不包含附件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End If
End Sub

' 获取剪贴板中附件的文件名
Private Async Function GetAttachedFileNamesFromClipboardAsync(clipboardData As IDataObject) As Task(Of List(Of String))
    Dim attachedFileNames As New List(Of String)()

    If Not clipboardData.GetDataPresent("FileGroupDescriptor") Then
        Return attachedFileNames
    End If

    Using descriptorStream As MemoryStream = TryCast(clipboardData.GetData("FileGroupDescriptor", True), MemoryStream)
        If descriptorStream IsNot Nothing Then
            Using streamReader As New StreamReader(descriptorStream)
                Dim streamContent As String = Await streamReader.ReadToEndAsync()
                Dim fileNames As String() = streamContent.Split(New Char() {ControlChars.NullChar}, StringSplitOptions.RemoveEmptyEntries)
                attachedFileNames.AddRange(fileNames.Skip(1))
            End Using
        End If
    End Using

    Return attachedFileNames
End Function

' 将剪贴板中的附件保存到磁盘
Private Async Function SaveAttachmentFromClipboardToFileAsync(clipboardData As IDataObject, destinationFilePath As String) As Task
    If Not clipboardData.GetDataPresent("FileContents") Then
        Return
    End If

    Using attachedFileStream As MemoryStream = TryCast(clipboardData.GetData("FileContents", True), MemoryStream)
        Using destinationFileStream As FileStream = File.Open(destinationFilePath, FileMode.OpenOrCreate)
            Await attachedFileStream.CopyToAsync(destinationFileStream)
        End Using
    End Using
End Function

内容的提问来源于stack exchange,提问作者Hugo Jiménez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:07:33