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

本地Excel粘贴至远程程序失败及内存异常问题求助

本地Excel文件复制到远程桌面程序并保存至临时文件夹的实现方案

问题背景

本地电脑的Excel文件需复制粘贴到远程桌面运行的程序中,后续通过Excel.Interop修改并另存。远程内部复制文件时,使用DataFormats.FileDrop可正常获取文件路径,但跨本地-远程粘贴时只能通过FileGroupDescriptorW获取文件名信息,解析时还会抛出**"An attempt was made to read or write protected memory..."**异常,无法获取文件内容。

解决方案

远程桌面跨会话剪贴板传输文件时,需同时处理FileGroupDescriptorW(文件元数据)和FileContents(文件内容)两个格式。以下是完整的解析与保存代码:

1. 定义Win32结构体(对应FileGroupDescriptorW)

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct FILEDESCRIPTORW
{
    public uint dwFlags;
    public Guid clsid;
    public System.Drawing.Size sizel;
    public System.Drawing.Point pointl;
    public uint dwFileAttributes;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
    public uint nFileSizeHigh;
    public uint nFileSizeLow;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string cFileName;
}

[StructLayout(LayoutKind.Sequential)]
private struct FILEGROUPDESCRIPTORW
{
    public uint cItems;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    public FILEDESCRIPTORW[] fgd;
}

2. 解析剪贴板数据并保存到临时文件夹

public static List<string> SaveRemoteCopiedFilesToTemp()
{
    List<string> tempFilePaths = new List<string>();
    IDataObject dataObject = Clipboard.GetDataObject();

    // 检查是否包含文件组描述符
    if (!dataObject.GetDataPresent("FileGroupDescriptorW"))
        return tempFilePaths;

    // 获取文件组描述符流
    using (MemoryStream fgStream = (MemoryStream)dataObject.GetData("FileGroupDescriptorW", true))
    {
        byte[] buffer = new byte[fgStream.Length];
        fgStream.Read(buffer, 0, buffer.Length);

        // 分配非托管内存并复制数据
        IntPtr hGlobal = Marshal.AllocHGlobal(buffer.Length);
        try
        {
            Marshal.Copy(buffer, 0, hGlobal, buffer.Length);
            FILEGROUPDESCRIPTORW fgd = Marshal.PtrToStructure<FILEGROUPDESCRIPTORW>(hGlobal);

            // 遍历每个文件
            for (int i = 0; i < fgd.cItems; i++)
            {
                // 计算当前文件描述符的内存偏移
                IntPtr fileDescPtr = IntPtr.Add(hGlobal, Marshal.SizeOf(typeof(uint)) + i * Marshal.SizeOf(typeof(FILEDESCRIPTORW)));
                FILEDESCRIPTORW fileDesc = Marshal.PtrToStructure<FILEDESCRIPTORW>(fileDescPtr);

                // 获取文件内容流
                if (dataObject.GetDataPresent("FileContents", true))
                {
                    using (MemoryStream fileStream = (MemoryStream)dataObject.GetData("FileContents", true))
                    {
                        // 生成临时文件路径
                        string tempPath = Path.Combine(Path.GetTempPath(), fileDesc.cFileName);
                        // 写入文件
                        using (FileStream fs = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
                        {
                            fileStream.CopyTo(fs);
                        }
                        tempFilePaths.Add(tempPath);
                    }
                }
            }
        }
        finally
        {
            // 释放非托管内存,避免内存泄漏
            Marshal.FreeHGlobal(hGlobal);
        }
    }

    return tempFilePaths;
}

3. 使用示例

// 获取保存到临时文件夹的文件路径
List<string> tempFiles = SaveRemoteCopiedFilesToTemp();
if (tempFiles.Count > 0)
{
    string excelPath = tempFiles[0]; // 取第一个Excel文件
    // 后续使用Excel.Interop打开并编辑
    Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
    Microsoft.Office.Interop.Excel.Workbook workbook = excelApp.Workbooks.Open(excelPath);
    // ... 编辑操作 ...
    workbook.SaveAs(@"C:\Remote\Edited_File.xlsx");
    workbook.Close();
    excelApp.Quit();

    // 可选:清理临时文件
    File.Delete(excelPath);
}

关键注意事项

  • 内存处理:解析FileGroupDescriptorW时必须正确处理非托管内存的分配与释放,这是避免保护内存异常的核心。
  • 权限:确保远程桌面程序拥有剪贴板访问权限,以及临时文件夹的读写权限。
  • 多文件处理:代码支持同时复制多个文件,可根据需求调整逻辑。

内容的提问来源于stack exchange,提问作者NadiaBallshek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:20:33