2012-02-03 17 views
6

Ho un progetto vb6 che ha un riferimento a una libreria com vb.net.Errore di runtime di binding tardivo in VB6 durante la creazione di un oggetto da un assembly .NET

il progetto funziona bene quando uso l'associazione anticipata come ad esempio:

Dim b as object 
Set b = new myComLib.testObject 

quando ho utilizzare l'associazione tardiva come ad esempio:

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

ottengo il seguente errore:

Run-time error '429': ActiveX component can't create object

Qualche idea?

grazie

+0

Ho appena provato questo ed entrambi i metodi di lavoro. Sono su XP e ho aggiunto myComLib.tlb come riferimento al progetto. Sei su XP o Win7? –

+0

sto usando xp. Ho registrato la libreria e anche copiato nella cartella del progetto (sia dll che file tlb) ho anche aggiunto un riferimento al progetto. Questo è il motivo per cui l'associazione anticipata funziona. Anche l'associazione tardiva dovrebbe funzionare. Ho anche provato ad aggiungere un riferimento a scrrun.dll ma ancora nulla. – reven

risposta

5

Le voci del Registro per la classe .NET interoperabilità COM in questo caso sono: -

HKEY_CLASSES_ROOT\myComLib.testObject 

contenente un valore CLSID e la voce CLSID sé

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

Sono replicato anche in

HKEY_LOCAL_MACHINE\SOFTWARE\Classes 

CreateObject utilizza le voci HKEY_CLASSES_ROOT per recuperare i dettagli del nome della classe passato in cui se si perdono si riceverà

Run-time error '429': ActiveX component can't create object

all'interno dell'IDE VB6, l'aggiunta di un riferimento al dll (nel caso di un L'assembly .NET, tramite il suo file tlb) ignora questa ricerca nel Registro di sistema consentendo in tal modo al binding anticipato di funzionare senza le voci del registro COM.

La classe deve essere registrata correttamente affinché CreateObject funzioni. Questo dovrebbe accadere come parte del processo di compilazione di Visual Studio, altrimenti è necessario registrarlo manualmente usando Regasm.

è possibile verificare questo comportamento nel modo seguente: -

1) Creare un nuovo VB.NET progetto myComLib registrazione per l'interoperabilità COM nel progetto Compilare le proprietà e aggiungere una classe testObject

Public Class testObject 

    Public Property TestProperty As String 

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

End Class 

2) Costruire myComLib

3) Creare un nuovo progetto VB6, aggiungere due pulsanti di comando a Form1 e il seguente codice

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) Eseguire il progetto VB6 (senza compilazione completa come che fallire)

Command2 popup una finestra di messaggio, comando 1 non riuscirà con

Compile Error: User-defined type not defined.

5) Interrompere il progetto e aggiungere un riferimento a myComLib via è TLB file di

6) Eseguire il progetto VB6 e entrambi i pulsanti dovrebbero ora lavorare

7) Andate in il registro di sistema e cancellare la voce HKEY_CLASSES_ROOT \ myComLib.testObject (questo può essere ricreato ricostruendo componente .NET, è necessario chiudere VB6 per effettuare la ricostruzione)

Command2 sarà ora riuscire con

Run-time error '429': ActiveX component can't create object

fino all'aggiunta della voce di registro.

+0

hai scritto HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSID \ ha un nome diverso da HKEY_CLASSES_ROOT. Perché sta succedendo? – reven

+0

Le voci del Registro di sistema si verificano sia in HKEY_CLASSES_ROOT che in HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSID ma CreateObject utilizza HKEY_CLASSES_ROOT. Poiché ho eseguito una ricerca nel registro da HKEY_CLASSES_ROOT \ myComLib.testObject, la voce successiva nel registro è HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSID. Aggiornerò la risposta –

+0

nel mio caso il createobject funziona con HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSID !!! – reven

0

Se si è l'impostazione ClassInterfaceType.None, è necessario aggiungere un attributo ProgId alla classe per consentire l'associazione tardiva.

Ad esempio:

[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"; 
    } 

}