MS Excel 2013的自动化加载项

问题描述:

我想在Visual Studio 2013中编写一个C#自动化加载项。目标是能够从MS Excel 2013中调用用C#编写的UDF。我已阅读了大部分关于这个问题的公开材料,并试图修改几个简单的例子,such asMS Excel 2013的自动化加载项

using System; 
using System.Net; 
using System.Runtime.InteropServices; 
using System.Globalization; 
using Microsoft.Win32; 

namespace MyFirstAddIn 
{ 
// Early binding. Doesn't need AutoDual. 
[Guid("5E6CD676-553F-481E-9104-4701C4DAB272")] 
[ComVisible(true)] 
public interface IFinancialFunctions 
{ 
    double Bid(string symbol); 
    double Ask(string symbol); 
    double[,] BidnAsk(string symbol, string direction = null); 
} 

[Guid("B9B7A498-6F84-43EB-A50C-6D26B72895DA")] 
[ClassInterface(ClassInterfaceType.None)] 
[ComVisible(true)] 
public class FinancialFunctions : IFinancialFunctions 
{ 
    // Private class members. 
    private static readonly WebClient webClient = new WebClient(); 
    private const string UrlTemplate = "http://finance.yahoo.com/d/quotes.csv?s={0}&f={1}"; 

    // Private method - data download. 
    private static double GetDoubleDataFromYahoo(string symbol, string field) 
    { 
     string request = string.Format(UrlTemplate, symbol, field); 
     string rawData = webClient.DownloadString(request); 

     return double.Parse(rawData.Trim(), CultureInfo.InvariantCulture); 
    } 

    // Public "interface" methods. 
    public double Bid(string symbol) 
    { 
     return GetDoubleDataFromYahoo(symbol, "b3"); 
    } 

    public double Ask(string symbol) 
    { 
     return GetDoubleDataFromYahoo(symbol, "b2"); 
    } 

    public double[,] BidnAsk(string symbol, string direction = null) 
    { 
     double bid = GetDoubleDataFromYahoo(symbol, "b3"); 
     double ask = GetDoubleDataFromYahoo(symbol, "b2"); 

     return direction == "v" ? new[,]{{bid}, {ask}} : new[,]{{bid, ask}}; 
    } 

    [ComRegisterFunctionAttribute] 
    public static void RegisterFunction(Type type) 
    { 
     Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable")); 
     RegistryKey key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true); 
     key.SetValue("",System.Environment.SystemDirectory + @"\mscoree.dll",RegistryValueKind.String); 
    } 

    [ComUnregisterFunctionAttribute] 
    public static void UnregisterFunction(Type type) 
    { 
     Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false); 
    } 

    private static string GetSubKeyName(Type type, string subKeyName) 
    { 
     System.Text.StringBuilder s = new System.Text.StringBuilder(); 
     s.Append(@"CLSID\{"); 
     s.Append(type.GUID.ToString().ToUpper()); 
     s.Append(@"}\"); 
     s.Append(subKeyName); 

     return s.ToString(); 
    } 
} 
} 

我已组装COM可见经由:

不幸的是,两者都没有VS 2013和2013年msexcel的代码示例下写入

项目 - >属性 - >应用程序 - >组装信息

而且我还在“构建”选项卡中注册了COM互操作。

构建完成后,我可以在注册表中看到注册成功,并且加载项在正确的GUID下注册。但是,当我打开Excel并转到开发人员 - >加载项 - >自动化时,我看不到列表中的加载项。我验证了我发布的代码适用于Excel 2010,但出于某种原因,我无法在Excel 2013中看到我的加载项。

任何人都可以帮助我解决这个问题吗?

好的,我找到了问题的原因。令人惊讶的是,事实证明,Visual Studio不具备在注册表中的正确树下自动注册64位dll的功能。解决方案不是为COM interop注册项目,而是手动添加命令来调用RegAsm的64位版本作为生成后事件。 dll的完整路径和名称需要包含,所以不幸的是,这不是一个完全自动化的解决方案。