Каким будет лучший способ предоставить определенные функции в надстройке Dotnet VSTO Excel для VBA, не требуя, чтобы пользователь был локальным администратором (то есть без регистрации COM, нет HttpListener)? Можно ли использовать очереди сообщений Microsoft из VBA?





Если я могу интерпретировать ваш вопрос так широко, как «Как предоставить Excel функциональность сборки .Net без регистрации COM», то отличным решением будет использование интерфейса Excel XLL. Обычно развертывается прокладка xll и связанная с ней библиотека .Net. Когда xll загружается, он отражается над dll и предоставляет функции Excel в нем.
Реализацию с открытым исходным кодом можно найти здесь http://exceldna.typepad.com/blog/2006/01/introduction_exc.html
Коммерческий, с закрытым исходным кодом, но более функциональный здесь http://www.managedxll.com/
Вы не можете просто создать их экземпляры как объекты COM, поскольку VSTO не будет работать в домене приложения по умолчанию.
Вот как я это сделал, что, по общему признанию, немного запутано. Это было с книгой VSTO, сохраненной в виде файла XLA, который в некотором смысле более гибок, чем надстройка чистого VSTO.
Вам необходимо сгенерировать библиотеку типов с помощью regasm.exe, на которую будет ссылаться ваш код VBA.
Создайте корневой класс фабрики в своей объектной модели .NET, который может создавать экземпляры любого из классов, которые вы хотите использовать в VBA (что-то вроде класса «Application» в объектных моделях Office).
Затем вам нужно найти способ передать ссылку на экземпляр этого фабричного класса в VBA. Как только VBA имеет ссылку на экземпляр этого фабричного класса, он может вызывать его методы для создания экземпляров любых других объектов в вашей объектной модели .NET.
Чтобы передать экземпляр в VBA, определите макрос в коде VBA следующим образом
Пример кода:
Private m_objMyFactory As Object
Public Sub RegisterFactory(MyFactory As Object)
On Error GoTo ErrHandler
Set m_objMyFactory = MyFactory
Exit Sub
ErrHandler:
MsgBox "An unexpected error occurred when registering the Factory component: " & Err.Description
Exit Sub
End Sub
Пример кода:
void ThisWorkbook_Open()
{
try
{
ThisApplication.Run("RegisterFactory",
new MyNamespace.MyFactory(),
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
catch (Exception ex)
{
MessageBox.Show("Load error: " + ex.ToString());
}
}
Есть еще несколько вопросов, которые необходимо учитывать, чтобы это работало надежно - если вы заинтересованы в том, чтобы следить за этим, дайте мне знать, и я опубликую более подробную информацию.
Возможно, вас заинтересует Excel4Net (он похож на ExcelDNA и ManagedXll, но проще в использовании):
Веб-сайт: http://www.excel4net.com
Просто для справки для будущих читателей: вы также можете взглянуть на этот вопрос:
Доступ к типам надстроек приложения VSTO из VBA (Excel)
и, в частности, в блог, на который есть ссылки:
Надстройки VSTO, COMAddIns и RequestComAddInAutomationService
Переопределив RequestComAddInAutomationService (), вы можете предоставить любую функциональность, которую хотите, путем определения класса Facade, который предоставляет точки входа для всех этих функций, и предоставления этого класса VBA.