2012-03-20 85 views
0

我正在为一个用户构建数学模型的项目工作,然后以不同的格式输出它们。现在我支持Python,Java,C++输出。这工作,我只是自动生成的代码,并称它为一天。COM Interop的DLL的运行时编译

然而,一个新的请求已经取得进展。用户希望能够使用Excel中的模型。我做了一些搜索,发现http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

所以这是一个很好的开始,但我需要以编程方式做到这一点。模型作为对象存储在更大的程序中。如果用户选择导出为Excel的DLL,我会采用一些样板代码并插入我想要使用的方法。

然而,好像我需要注册为COM互操作的代码。我的测试代码创建一个DLL,我可以使用C#并访问它的方法。但是试图在Excel 2000中添加一个引用(我知道,我知道,公司很糟糕)VBA不起作用。看起来没有创建TLB文件,所以没有什么要加载的。

如果我把生成的代码编译为一个独立的检查完化妆COM可见并注册为COM互操作盒,产生TLB但Excel的VBA抛出一个自动化错误。

所以实际的问题。

1)我怎么能在运行时创建一个DLL,它为Com可见和Reistered为COM互操作?

2)如何获得Excel中发挥好它。

简单的例子DLL的代码如下:

using System; 
using System.Runtime.InteropServices; 

namespace VSN 
{ 

    [ComVisibleAttribute(true)] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    public class VSNFunctions 
    { 
     public VSNFunctions() 
     { 
     } 

     /// <summary> 
     /// Adds 2 variables together. 
     /// </summary> 
     /// <param name=\"v1\">First Param</param> 
     /// <param name=\"v2\">Second Param</param> 
     /// <returns>Sum of v1 and v2</returns> 
     public double Add2(double v1, double v2) 
     { 
      return v1 + v2; 
     } 
     public double Sub2(double v1, double v2) 
     { 
      return v1 - v2; 
     } 
     public double Mul2(double v1, double v2) 
     { 
      return v1 * v2; 
     } 
     public double div2(double v1, double v2) 
     { 
      return v1/v2; 
     } 

     [ComRegisterFunctionAttribute] 
     public static void RegisterFunction(Type t) 
     { 
      Microsoft.Win32.Registry.ClassesRoot.CreateSubKey("CLSID\\{"+t.GUID.ToString().ToUpper() + "}\\Programmable"); 
     } 


     [ComUnregisterFunctionAttribute] 
     public static void UnregisterFunction(Type t) 
     { 
      Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey("CLSID\\{"+t.GUID.ToString().ToUpper() + "}\\Programmable"); 
     } 
    } 
} 

代码来构建DLL programmitcally如下:

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp"); 
CompilerParameters parameters = new CompilerParameters(); 
parameters.GenerateExecutable = false; 
String exeName = String.Format(@"{0}\{1}.dll", System.Environment.CurrentDirectory, "VSNTest"); 
MessageBox.Show(exeName); 
parameters.OutputAssembly = exeName; 

parameters.CompilerOptions = "/optimize"; 

CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, DLLString); 

回答