ubienewbie
ubienewbie

Reputation: 2421

Convert Excel RTD library to Excel-DNA while retaining =RTD( interface (64 bit Excel)

I have written an IRTDServer in C# and it works fine.

I'd like to convert the code to use Excel DNA (for various reasons, but the most important being that I'd like to have multiple addins loaded each in their own appdomain).

However, in the short term, I'd like to preserve the "old" way of calling, i.e. =RTD("ProgId",,"MyCoolFunction","Arg1").

I'm using this sample project to get started with:

https://github.com/Excel-DNA/Samples/tree/master/RtdClocks/RtdClock-ExcelRtdServer

I have it working so that I can use =dnaRtdClock_ExcelRtdServer() in Excel and it gives me time updates every few seconds.

  1. Is it going to be possible to call it via =RTD(" ...
  2. If so, am I correct that the function to enter into Excel would be =RTD("RtdClock.ClockServer",,"dummy/ignored").
  3. And then mainly:

What do I need to do to be able to call that same function via =RTD("RtdClock.ClockServer",,"dummy/ignored")

I guess I should also ask a fourth question:

If I am able to successfully access the IRTDServer via the =RTD( function call, will Excel/Excel-DNA be loading the implementing DLL into the FullyTrustedSandbox or the DefaultDomain? [after all, the whole reason I'm doing this conversion to Excel DNA is to get the AppDomain feature].

Things I've tried:

  1. I added a GUID to RTDClockServer project.
  2. I ran %SystemRoot%\Microsoft.Net\Framework64\v4.0.30319\RegAsm.exe RtdClock-ExcelRtdServer.dll /codebase. Initially it complained about ExcelDna.Integration being missing. So I changed the reference to that package to be CopyLocal=True.
  3. I checked the registry. It does have all the COM registration entries that I would expect from registering an RTD server.
  4. I've tried adding =RTD("RtdClock.ClockServerRTD",,) as function call. I see that it does load my DLL and hits a break point, but ONLY the ServerTerminate breakpoint (so, not the ServerStart for example). I also see that the AppDomain in this case is DefaultDomain, not the "FullyTrustedSandBox: ..."
  5. I've tried running c:\windows\system32\regsvr32 against the DLL, against all of the *.xll files in the following directory: [note: I started with the RtdClock-ExcelRtdServer-AddIn64-packed.xll and RtdClock-ExcelRtdServer-AddIn64.xlls as they seemed most logical too me.] These consistently fail silently from the command line, but in the EventViewer I see an error:

    Application: regsvr32.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.InvalidOperationException at ExcelDna.Integration.RunMacroSynchronization.Register() at ExcelDna.Integration.SynchronizationWindow..ctor() at ExcelDna.Integration.SynchronizationManager.Install() at ExcelDna.Integration.DnaLibrary.Initialize() at ExcelDna.Integration.DnaLibrary.InitializeRootLibrary(System.String)

     Directory of C:\Users\xxxx\source\repos\ExcelDna-Samples\RtdClocks\RtdClock-ExcelRtdServer\bin\Debug

    02/01/2020  10:38    <DIR>          .
    02/01/2020  10:38    <DIR>          ..
    02/01/2020  10:38           629,248 RtdClock-ExcelRtdServer-AddIn-packed.xll
    02/01/2020  08:31               939 RtdClock-ExcelRtdServer-AddIn.dna
    09/09/2015  22:49           751,104 RtdClock-ExcelRtdServer-AddIn.xll
    02/01/2020  10:38           539,136 RtdClock-ExcelRtdServer-AddIn64-packed.xll
    02/01/2020  08:31               939 RtdClock-ExcelRtdServer-AddIn64.dna
    09/09/2015  22:49           660,992 RtdClock-ExcelRtdServer-AddIn64.xll
    02/01/2020  10:38             6,144 RtdClock-ExcelRtdServer.dll
    02/01/2020  10:38            17,920 RtdClock-ExcelRtdServer.pdb

enter image description here

namespace RtdClock_ExcelRtdServer
{
    [Guid("2838E6F0-B2CA-4FC9-A9AF-7F834CBC595C")]
    [ComVisible(true)]                   // Required since the default template puts [assembly:ComVisible(false)] in the AssemblyInfo.cs
    [ProgId(RtdClockServer.ServerProgId)]     //  If ProgId is not specified, change the XlCall.RTD call in the wrapper to use namespace + type name (the default ProgId)
    public class RtdClockServer : ExcelRtdServer  
    {
        public const string ServerProgId = "RtdClock.ClockServer";

        // Using a System.Threading.Time which invokes the callback on a ThreadPool thread 
        // (normally that would be dangerous for an RTD server, but ExcelRtdServer is thread-safe)
        Timer _timer;
        List<Topic> _topics;

        protected override bool ServerStart()
        {
            _timer = new Timer(timer_tick, null, 0, 1000);
            _topics = new List<Topic>();
            return true;
        }

Note: OS Name Microsoft Windows 10 Pro Version 10.0.18362 Build 18362 Microsoft Excel for Office 365 Version 1911 Build 12228.20364 Click-to-Run Monthly Channel

Upvotes: 2

Views: 1024

Answers (1)

Govert
Govert

Reputation: 16907

I think you will need to run RegSvr32.exe RtdClock-ExcelRtdServer-AddIn64-packed.xll or something similar, to register the .xll file as the COM library serving up the RTD server. Doing Regasm.exe on the .dll file makes a mess, causing the COM registration to go against mscorlib which hosts the .dll in the default AppDomain as you see.

Upvotes: 1

Related Questions