Я работаю над проектом, который создает математические модели для пользователя, а затем может выводить их в разных форматах. Прямо сейчас я поддерживаю вывод в Python, Java, C++. Это работает, я просто автогенерирую код и называю его днем.Runtime Компиляция DLL для COM Interop
Однако новый запрос был сделан. Пользователь хочет иметь возможность использовать модели из Excel. Я сделал поиск и нашел http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/
Так что это хороший старт, но мне нужно сделать это программно. Модели хранятся как объекты в более крупной программе. Если пользователь выбирает экспорт в качестве библиотеки DLL для Excel, я бы взял код шаблона и ввел методы, которые я хотел бы использовать.
Однако, похоже, мне нужно зарегистрировать код для COM Interop. Мой тестовый код создает DLL, я могу использовать его C# и получить доступ к его методам. Но, пытаясь добавить ссылку в Excel 2000 (знаю, я знаю, корпоративный отстой) VBA не работает. Кажется, что ни один файл TLB не создан, поэтому ему нечего загружать.
Если я беру сгенерированный код, скомпилируем его как автономный, проверив make COM Visible и зарегистрировав для com interop boxes, TLB создается, но Excel VBA вызывает ошибку автоматизации.
Итак, актуальные вопросы.
1) Как создать во время выполнения DLL, видимую и перезаписываемую для 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);