Я боролся с этим несколько часов и не могу найти, что я делаю неправильно.
Я создал новый проект DLL С#, вот содержимое единственного класса, который он содержит:
using System;
using System.Runtime.InteropServices;
namespace PolygonSl {
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Config {
[ComVisible(true)]
public string GetCompany() {
return "POL";
}
}
}
Я в основном удаляю из него все, пытаясь заставить его работать, единственная ссылка — System
.
Я проверил флаг Make assembly COM-Visible
на Assembly Information
, и мой проект подписан (требуются швы для кодовой базы).
Компилируется нормально, после этого я вызвал RegAsm.exe
, дал ей свою dll, добавил /codebase
и /tlb
, команда прошла успешно.
Когда я перехожу к своему проекту VBA, я могу добавить свой новый файл tlb в ссылки, и он работает нормально. После этого я могу использовать его в своем коде, автозаполнение работает, и я могу компилировать без ошибок.
Затем, когда я выполняю, я получил это:
Run-time error '430':
Class does not support Automation or does not support expected interface
Вот мой пример кода в VBA:
Private Sub Button1_Click()
'With CreateObject("PolygonSl.Config")
With New PolygonSl.Config
MessBox .GetCompany, MB_OK, "Test"
End With
End Sub
Я попробовал позднее связывание, и мой код работает с ним нормально, но я хотел бы иметь возможность использовать автозаполнение.
У кого-нибудь есть предложение о том, что я мог бы попытаться заставить его работать?
Изменить (добавление некоторых сведений о моей среде)
@HansPassant, у меня есть созданный мной файл cmd, который каждый раз регенерирует файл tbl. Я почти уверен, что каждый раз запускаю regasm unregister и register, так как это никогда не срабатывало, я внимательно слежу за каждым шагом. Я только что попытался проверить регистрацию для COM-взаимодействия (после того, как отменил регистрацию другого), и у меня тот же результат, только работает поздняя привязка.
@HansPassant, в мониторе процессов я вижу запись класса и интерфейса RegAsm (мой фактический код такой же, как у Freeflow). Но когда я смотрю на свою программу, я вижу, что она читает хороший класс, но не читает интерфейс. После этого много чего не находит но ничего с clsid.
Я думаю, вам нужно определить интерфейс, чтобы иметь возможность видеть getcompany.
using System;
using System.Runtime.InteropServices;
namespace PolygonSl
{
[Guid("6DC1808F-81BA-4DE0-9F7C-42EA11621B7E")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IConfig
{
string GetCompany();
}
[Guid("434C844C-9FA2-4EC6-AB75-45D3013D75BE")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
public class Config : IConfig
{
public string GetCompany()
{
return "POL";
}
}
}
Вы можете сгенерировать интерфейс автоматически, поместив курсор в определение класса и используя Edit.Refactor.ExtractInterface.
Я должен признать, что здесь я нахожусь на пределе своих возможностей, и вышеизложенное составлено на основе примеров, которые я видел в других местах.
Редактировать
Следующий тестовый код отлично работает на моем ПК
Option Explicit
Sub polygontest()
Dim my_polygon As SOPolygon.Config
Set my_polygon = New SOPolygon.Config
Debug.Print my_polygon.GetCompany
End Sub
Где SOPolygon — название проекта.
У меня точно такой же результат. При использовании ссылки я получил ошибку, но позднее связывание работает так же, как и раньше.
@AlexDupuis: Может ли это быть так же просто, как тот факт, что вы используете MessBox, а не MsgBox? Я добавил код VBA для теста, который правильно возвращает POL на моей машине. Пожалуйста, убедитесь, что у вас есть Option Explicit в качестве первой строки в каждом из ваших модулей/классов.
Да, у меня был Option Explicit, а MessBox — это что-то из приложения, которое я использую (Dynamics SL). Чтобы быть уверенным, я скопировал оба ваших источника и вставил их на свою сторону, я даже использовал Excel, и у меня тот же результат. Может быть, это что-то в моей настройке. Я использую VS2008, FW 3.5, компилирую в Release x86.
Я использую VS2019Community, FW 4.5. Подозреваю, что дело может быть в этом.
Попробую обновиться на снапшоте этого сервера, чтобы быть уверенным, что ничего не тормозит ;)
Вы можете найти эту ссылку полезной. bestsolutions.com/csharp/excel-interop/… В VS2017 и 2019 нет необходимости выполнять regasm отдельно, если в диалоговых окнах свойств проекта отмечены все правильные поля.
У меня есть доступ к VS2017 в другой системе, я создал точно такой же проект и скопировал DLL на виртуальную машину, использовал RegAsm, и он отлично работал. Возможно что-то не так с 2008. Я проверю, чтобы установить его на свою виртуальную машину.
Самая основная причина заключается в том, что вы изменили DLL, но забыли удалить и добавить измененный .tlb в свой проект VBA. Или просто забыли снова запустить Regasm, одна из веских причин позволить VS делать это автоматически.