2012-02-03 1 views
6

私はvb.net comライブラリへの参照を持つvb6プロジェクトを持っています。.NETアセンブリからオブジェクトを作成するときにVB6で実行時バインディング実行時エラーが発生しました

私は早期のようなバインディングを使用する場合、プロジェクトがうまく実行されます。

Dim b as object 
Set b = new myComLib.testObject 

私のような遅延バインディングを使用する場合:

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

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

私は次のエラーを取得します

アイデア?この場合、.NETのCOM相互運用機能のクラスの

おかげ

+0

私はこれを試してみたとの両方の方法が働きます。私はXPで、私はプロジェクトへの参照としてmyComLib.tlbを追加しました。あなたはXPかWin7にいますか? –

+0

私はxpを使用しています。私はライブラリを登録して、プロジェクトフォルダ(dllファイルとtlbファイル)にコピーしました。プロジェクトへの参照も追加しました。そのため、初期バインディングが機能します。遅い拘束も働くはずです。私もscrrun.dllへの参照を追加しようとしましたが、まだ何もありません。 – reven

答えて

5

レジストリエントリは次のとおりです。 -

彼らはCLSID値とCLSIDエントリ自体

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

を含む

HKEY_CLASSES_ROOT\myComLib.testObject 

HKEY_LOCAL_MACHINE\SOFTWARE\Classes 
あなたがある場合には(DLLへの参照を追加し、VB6のIDE内

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

受け取ることになります

のCreateObjectは、彼らが欠けている場合はそうで渡されたクラス名の詳細を取得するために、HKEY_CLASSES_ROOTエントリを使用しています.NETアセンブリ、tlbファイル経由)は、このレジストリ検索をバイパスします。これにより、COMレジストリエントリなしで初期バインディングが機能します。

CreateObjectが動作するためには、クラスを正しく登録する必要があります。これはVisual Studioビルドプロセスの一部として実行する必要があります。それ以外の場合は、Regasmを使用して手動で登録する必要があります。

次の手順で、この動作をテストすることができます -

1)新しいVBを作成します。NETプロジェクトmyComLibプロパティをコンパイルし、testObject

Public Class testObject 

    Public Property TestProperty As String 

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

End Class 

2クラスを追加プロジェクトでCOM相互運用機能の登録)myComLib

3を構築するには)新しいVB6のプロジェクトを作成し、Form1の次のコードに2つのコマンドボタンを追加それが失敗するよう

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)

Command2のメッセージボックスをポップアップします)フルコンパイルせずに(VB6のプロジェクトを実行し、コマンド1は

Compile Error: User-defined type not defined.

5で失敗します)プロジェクトを停止し、それがTLBファイル

6のヴィアmyComLibへの参照を追加)VB6のプロジェクトを実行し、両方のボタンが今

7を動作するはずです)に移動しますレジストリとHKEY_CLASSES_ROOT \ myComLib.testObjectエントリを削除する(これは.NETコンポーネントを再構築することにより、再作成することができ、再構築を実行するためにVB6を閉じる必要があります)

コマンド2が今

で失敗します10

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

レジストリエントリが再追加されるまで。

+0

HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSID \にはHKEY_CLASSES_ROOTとは異なる名前があります。なぜこうなった? – reven

+0

レジストリエントリは、HKEY_CLASSES_ROOTとHKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSIDの両方で発生しますが、CreateObjectはHKEY_CLASSES_ROOTを使用します。私はHKEY_CLASSES_ROOT \ myComLib.testObjectからレジストリ検索を行ったので、レジストリの次のエントリはHKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSIDです。私は答えを更新します。私の場合、 –

+0

の場合、createobjectはHKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ CLSIDで動作しています! – reven

0

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

}