Ошибка позднего связывания во время выполнения в VB6 при создании объекта из сборки .NET - PullRequest
6 голосов
/ 03 февраля 2012

У меня есть проект vb6, в котором есть ссылка на библиотеку vb.net com.

проект работает хорошо, когда я использую раннее связывание, например:

Dim b as object
Set b = new myComLib.testObject

при использовании позднего связывания, например:

Dim b as object
Set b = CreateObject("myComLib.testObject")

я получаю следующую ошибку:

Ошибка времени выполнения '429': компонент ActiveX не может создать объект

Есть идеи?

спасибо

Ответы [ 2 ]

5 голосов
/ 03 февраля 2012

Записи реестра для класса .NET COM Interop в этом случае: -

HKEY_CLASSES_ROOT\myComLib.testObject 

, содержащие значение CLSID и саму запись CLSID

HKEY_CLASSES_ROOT\CLSID\<<myComLib.testObject\CLSID value>>

Они также реплицируютсяв

HKEY_LOCAL_MACHINE\SOFTWARE\Classes

CreateObject использует записи HKEY_CLASSES_ROOT для получения сведений о переданном имени класса, поэтому, если они отсутствуют, вы получите

Ошибка времени выполнения '429'Компонент ActiveX не может создать объект

В среде IDE VB6 добавление ссылки на dll (в случае сборки .NET через файл tlb) обходит этот поиск в реестре, тем самым позволяяраннее связывание для работы без записей реестра COM.

Класс должен быть правильно зарегистрирован для работы CreateObject.Это должно происходить как часть процесса сборки Visual Studio, в противном случае его необходимо зарегистрировать вручную с помощью Regasm.

Это поведение можно проверить, выполнив следующие действия: -

1) Создайте новыйПроект VB.NET myComLib регистрируется для COM Interop в проекте. Скомпилируйте свойства и добавьте класс testObject

Public Class testObject

    Public Property TestProperty As String

    Public Function TestFunction() As String
        Return "return"
    End Function

End Class

2) Создайте myComLib

3) Создайте новый проект VB6, добавьте две командные кнопкив Form1 и следующий код

Private Sub Command1_Click()
   Dim b As Object
   Set b = New myComLib.testObject
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

Private Sub Command2_Click()
   Dim b As Object
   Set b = CreateObject("myComLib.testObject")
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

4) Запустите проект VB6 (без полной компиляции, поскольку это не удастся)

Command2 выведет всплывающее окно с сообщением, Command1 завершится ошибкой с

Ошибка компиляции: пользовательский тип не определен.

5) Остановите проект и добавьте ссылку на myComLib через его файл tlb

6) ЗапуститеПроект VB6 и обе кнопки теперь должны работать

7) Зайдите в реестр и удалите запись HKEY_CLASSES_ROOT \ myComLib.testObject (это можно воссоздать с помощью Перестройки компонента .NET, вамed, чтобы закрыть VB6 для выполнения перестроения)

Command2 теперь не будет работать с

Ошибка времени выполнения '429': компонент ActiveX не может создать объект

до повторного добавления записи реестра.

0 голосов
/ 10 февраля 2015

Если вы настроены на ClassInterfaceType.None, вы должны добавить атрибут ProgId в свой класс, чтобы разрешить позднюю привязку.

Например:

[Guid("B1E17DF6-9578-4D24-B578-9C70979E2F05")]
public interface _Class1
{
    [DispId(1)]
    string TestingAMethod();
}

[Guid("197A7A57-E59F-41C9-82C8-A2F051ABA53C")]
[ProgId("Rubberduck.SourceControl.Class1")]
[ClassInterface(ClassInterfaceType.None)]
public class Class1 : _Class1
{
    public string TestingAMethod()
    {
        return "Hello World";
    }

}
...