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

.NET 4.x迁移至.NET 7后RTD公式无法正常工作

.NET 7 RTD Server 在Excel中显示N/A问题排查

我有一个在.NET Framework 4.x中运行正常的RTD Server实现,升级到.NET 7后出现问题。已用regsvr32.exe成功注册comhost.dll,但Excel中所有包含RTD公式的单元格均显示“N/A”,而COM客户端应用可正常运行。


代码文件

Server.cs

using System;
using System.Runtime.InteropServices;
using com.lightstreamer.client;
using Microsoft.Office.Interop.Excel;

namespace Examples.RtdDemo
{
    [ComVisible(true)]
    [Guid("DB1797F5-7198-4411-8563-D05F4E904956")]
    [ProgId("lightstreamer.rtdnew12")]
    public class LsRtdServer : IServer
    {
        private int pi = 0;

        int IRtdServer.ServerStart(IRTDUpdateEvent CallbackObject)
        {
            return (int)pi;
        }

        object IRtdServer.ConnectData(int TopicID, ref Array Strings, ref bool GetNewValues)
        {
            pi += TopicID;

            return ""+pi;
        }

        Array IRtdServer.RefreshData(ref int TopicCount)
        {
            object[,] data = new object[1, 1];

            data[0,0] = ""+pi;

            return data;
        }

        void IRtdServer.DisconnectData(int TopicID)
        {
            // .
        }

        int IRtdServer.Heartbeat()
        {
                return 0;
        }

        void IRtdServer.ServerTerminate()
        {
            // ..
        }
    }
}

IServer.cs

using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

[ComVisible(true)]
[Guid("BA9AC84B-C7FC-41CF-8B2F-1764EB773D4B")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IServer : IRtdServer
{

}

项目文件(.csproj)

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <TargetFramework Condition="'$(DefaultALC)' == 'True'">net8.0</TargetFramework>

    <!-- Indicate the assembly is providing a COM server -->
    <EnableComHosting>True</EnableComHosting>

    <!-- Generate a RegFree COM manifest -->
    <EnableRegFreeCom Condition="'$(RegFree)' == 'True'">True</EnableRegFreeCom>
</PropertyGroup>

<ItemGroup>
    <!-- Used in lieu of a Primary Interop Assembly (PIA) -->
    <Compile Include="../COMContract/*.cs" />
</ItemGroup>

<ItemGroup>
    <PackageReference Include="Lightstreamer.DotNetStandard.Client" Version="6.0.0-beta.2" />
    <PackageReference Include="Microsoft.Office.Interop.Excel" Version="15.0.4795.1001" />
</ItemGroup>

<ItemGroup>
    <RuntimeHostConfigurationOption Condition="'$(DefaultALC)' == 'True'" Include="System.Runtime.InteropServices.COM.LoadComponentInDefaultContext" Value="true" />
</ItemGroup>

<Target Name="ServerUsage" Condition="'$(RegFree)' != 'True'" AfterTargets="Build">
    <Message Importance="High" Text="%0a************************************%0a*** $(MSBuildProjectName) usage instructions ***%0a************************************" />
    <Message Importance="High" Text="The server must be COM registered in order to activate.%0aThe following commands must be executed from an elevated command prompt." />
    <Message Importance="High" Text="Register:%0a    regsvr32.exe &quot;$(ProjectDir)$(OutputPath)$(ComHostFileName)&quot;" />
    <Message Importance="High" Text="Unregister:%0a    regsvr32.exe /u &quot;$(ProjectDir)$(OutputPath)$(ComHostFileName)&quot;" />
</Target>

<Target Name="ServerUsage_RegFree" Condition="'$(RegFree)' == 'True'" AfterTargets="Build">
    <Message Importance="High" Text="%0a************************************%0a*** $(MSBuildProjectName) usage instructions ***%0a************************************" />
    <Message Importance="High" Text="A RegFree COM manifest has been created for the server.%0aThe manifest '@(RegFreeComManifest-&gt;%(Filename)%(Extension)')' must be included during server deployment.%0aThe COMServer project will copy all required outputs to the COMClient output directory." />

    <ItemGroup>
        <ServerOutput Include="$(OutputPath)*.dll" />
        <ServerOutput Include="$(OutputPath)*.runtimeconfig.json" />
        <ServerOutput Include="$(OutputPath)*.deps.json" />
        <ServerOutput Include="$(OutputPath)*.manifest" />
    </ItemGroup>

    <!-- Deploy all required server outputs -->
    <Copy SourceFiles="@(ServerOutput)" DestinationFolder="../COMClient/$(OutputPath)" />
</Target>

<Target Name="Clean_RegFree" AfterTargets="Clean">
    <ItemGroup>
        <ServerOutputToDelete Include="../COMClient/$(OutputPath)COMServer.*" />
    </ItemGroup>
    <!-- Cleanup deployed server outputs -->
    <Delete Files="@(ServerOutputToDelete)" />
</Target>
</Project>

问题排查与修复建议

从实现和配置来看,以下几点是核心问题:

1. IRTDServer接口实现不符合Excel规范

  • ServerStart返回值错误:Excel要求该方法返回1表示初始化成功,返回0会被判定为启动失败,直接导致RTD连接中断。同时必须保存IRTDUpdateEvent回调对象,后续更新需要用它触发Excel刷新:
    private IRTDUpdateEvent _callback;
    int IRtdServer.ServerStart(IRTDUpdateEvent CallbackObject)
    {
        _callback = CallbackObject;
        return 1; // 返回1表示初始化成功
    }
    
  • Heartbeat返回值错误:返回0会让Excel认为服务器已停止,需返回1维持连接:
    int IRtdServer.Heartbeat()
    {
        return 1;
    }
    
  • RefreshData格式错误:Excel期望返回的是2维数组,第一维代表属性(主题ID、值),第二维代表主题数量。你的实现维度错误,且未正确设置TopicCount:
    Array IRtdServer.RefreshData(ref int TopicCount)
    {
        TopicCount = 1; // 实际主题数量
        object[,] data = new object[2, TopicCount];
        data[0, 0] = 1; // 对应TopicID
        data[1, 0] = pi.ToString(); // 对应主题值
        return data;
    }
    

2. 接口继承导致的COM类型歧义

自定义IServer接口继承IRTDServer可能导致COM类型库生成异常,建议直接让LsRtdServer实现IRTDServer,去掉中间接口:

[ComVisible(true)]
[Guid("DB1797F5-7198-4411-8563-D05F4E904956")]
[ProgId("lightstreamer.rtdnew12")]
public class LsRtdServer : IRTDServer
{
    // 直接实现IRTDServer所有方法
}

3. 位数不匹配

Excel分32位和64位版本,必须确保你的RTD Server编译位数与Excel一致:

  • 在项目属性中明确设置目标平台为x86或x64,而非AnyCPU
  • 注册对应位数的comhost.dll

4. COM加载上下文配置

.NET 7默认会在独立的程序集加载上下文(ALC)中加载COM组件,可能导致与Excel交互异常。移除项目文件中的条件编译,强制启用默认上下文加载:

<ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Runtime.InteropServices.COM.LoadComponentInDefaultContext" Value="true" />
</ItemGroup>

验证步骤

  1. 修改代码后重新编译,确保目标平台与Excel位数一致
  2. 管理员命令行重新注册:
    regsvr32.exe "你的输出路径\comhost.dll"
    
  3. 打开Excel测试公式:=RTD("lightstreamer.rtdnew12",, "测试参数")
  4. 启用Excel RTD日志排查细节:Excel选项 -> 高级 -> 常规 -> 勾选“启用RTD服务器日志”

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:27:08