VB6 automation error trying to use a COM-exposed C# DLL

T

Tremendo

Hi,

I have two PCs:
PC1: Visual Studio 2005 (including .NET framework 2.0.
PC2: Visual Studio 6 (using Visual Basic 6) + .NET framework 2.0 installed separately.

On PC1 I wrote and built a C# DLL (see code below), and created one .tlb and one .reg file to expose
its methods to COM.

On PC2 I copied the .dll, .tlb and .reg into WINDOWS\system32, and executed the .reg to insert new
entries to the registry. In Visual Basic 6, I created a new project, and added a reference to the
..tlb. So far, everything seems to be ok. I can see the class in the object inspector, and browse its
methods and enumerations. Also, the tool that shows as I type the valid methods and parameters works
ok. Compilation to exe works fine. Problems start at run time. Just trying to instantiate one
instance of the COM exposed class gives me a "Run-time error '-2147024894 (80070002) Automation
error'". See VB6 code below, too. Both listings have dummy code.

Any hint about what can this be due to?

Thank you,
Tremendo


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace N_Proc_CC1100_Test
{
public enum RadiobandTypes
{
RadiobandR =0,
RadiobandRC,
RadiobandRCS,
RadiobandT
}
// =========================================================================
[GuidAttribute("AEB5062F-6695-4484-B07A-53C37A99E92B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface _C_Proc_CC1100_Test
{
[DispIdAttribute(1)]
bool EnterTestMode(int RadiobandType);

[DispIdAttribute(2)]
bool LeaveTestMode();

[DispIdAttribute(3)]
bool GetSoftwareVersion(out int version);

[DispIdAttribute(4)]
bool TestRF(out double PeakFrequency_MHz,out double PeakPower_dBm);

[DispIdAttribute(5)]
bool SetOutputs(int outputs);

[DispIdAttribute(6)]
bool GetInputs(out int inputs);
}
// =========================================================================
[GuidAttribute("A9BA5B44-A432-44ab-9AFA-6C8058B20AA8")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ProgIdAttribute("N_Test.C_Test")]
public class C_Proc_CC1100_Test : _C_Proc_CC1100_Test
{
public RadiobandTypes RadiobandType;
public bool InTestMode;
// .....................................................................
public C_Proc_CC1100_Test()
{
RadiobandType =RadiobandTypes.RadiobandR;
InTestMode =false;
}
// .....................................................................
public bool EnterTestMode(int RadiobandType)
{
this.RadiobandType =(RadiobandTypes)RadiobandType;

InTestMode =true;
return(true);
}
// .....................................................................
public bool LeaveTestMode()
{
InTestMode =false;
return(true);
}
// .....................................................................
public bool GetSoftwareVersion(out int version)
{
version =(int)0x1234;
return(true);
}
// .....................................................................
public bool TestRF(out double PeakFrequency_MHz,out double PeakPower_dBm)
{
PeakFrequency_MHz =868.9;
PeakPower_dBm =-65.0;
return(true);
}
// .....................................................................
public bool SetOutputs(int outputs)
{
return(true);
}
// .....................................................................
public bool GetInputs(out int inputs)
{
inputs =(int)0x5678;
return(true);
}
// .....................................................................
} // C_Proc_CC1100_Test
// =========================================================================
} // N_Proc_CC1100_Test

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Private Sub Command1_Click()

Dim oXXX As C_Proc_CC1100_Test
Set oXXX = New C_Proc_CC1100_Test

End Sub

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
W

Willy Denoyette [MVP]

Tremendo said:
Hi,

I have two PCs:
PC1: Visual Studio 2005 (including .NET framework 2.0.
PC2: Visual Studio 6 (using Visual Basic 6) + .NET framework 2.0 installed separately.

On PC1 I wrote and built a C# DLL (see code below), and created one .tlb and one .reg file
to expose
its methods to COM.

On PC2 I copied the .dll, .tlb and .reg into WINDOWS\system32, and executed the .reg to
insert new
entries to the registry. In Visual Basic 6, I created a new project, and added a reference
to the
.tlb. So far, everything seems to be ok. I can see the class in the object inspector, and
browse its
methods and enumerations. Also, the tool that shows as I type the valid methods and
parameters works
ok. Compilation to exe works fine. Problems start at run time. Just trying to instantiate
one
instance of the COM exposed class gives me a "Run-time error '-2147024894 (80070002)
Automation
error'". See VB6 code below, too. Both listings have dummy code.

Any hint about what can this be due to?

Thank you,
Tremendo


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace N_Proc_CC1100_Test
{
public enum RadiobandTypes
{
RadiobandR =0,
RadiobandRC,
RadiobandRCS,
RadiobandT
}
// =========================================================================
[GuidAttribute("AEB5062F-6695-4484-B07A-53C37A99E92B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface _C_Proc_CC1100_Test
{
[DispIdAttribute(1)]
bool EnterTestMode(int RadiobandType);

[DispIdAttribute(2)]
bool LeaveTestMode();

[DispIdAttribute(3)]
bool GetSoftwareVersion(out int version);

[DispIdAttribute(4)]
bool TestRF(out double PeakFrequency_MHz,out double PeakPower_dBm);

[DispIdAttribute(5)]
bool SetOutputs(int outputs);

[DispIdAttribute(6)]
bool GetInputs(out int inputs);
}
// =========================================================================
[GuidAttribute("A9BA5B44-A432-44ab-9AFA-6C8058B20AA8")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ProgIdAttribute("N_Test.C_Test")]
public class C_Proc_CC1100_Test : _C_Proc_CC1100_Test
{
public RadiobandTypes RadiobandType;
public bool InTestMode;
// .....................................................................
public C_Proc_CC1100_Test()
{
RadiobandType =RadiobandTypes.RadiobandR;
InTestMode =false;
}
// .....................................................................
public bool EnterTestMode(int RadiobandType)
{
this.RadiobandType =(RadiobandTypes)RadiobandType;

InTestMode =true;
return(true);
}
// .....................................................................
public bool LeaveTestMode()
{
InTestMode =false;
return(true);
}
// .....................................................................
public bool GetSoftwareVersion(out int version)
{
version =(int)0x1234;
return(true);
}
// .....................................................................
public bool TestRF(out double PeakFrequency_MHz,out double PeakPower_dBm)
{
PeakFrequency_MHz =868.9;
PeakPower_dBm =-65.0;
return(true);
}
// .....................................................................
public bool SetOutputs(int outputs)
{
return(true);
}
// .....................................................................
public bool GetInputs(out int inputs)
{
inputs =(int)0x5678;
return(true);
}
// .....................................................................
} // C_Proc_CC1100_Test
// =========================================================================
} // N_Proc_CC1100_Test

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Private Sub Command1_Click()

Dim oXXX As C_Proc_CC1100_Test
Set oXXX = New C_Proc_CC1100_Test

End Sub

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



You need to regasm the dll on the target system. You should also not install this in a
private folder not in a system folder like System32, use the "/codebase " option when
running regasm or register the dll in the GAC if you need this server to be accessible from
multiple clients.

Willy.
 
W

Willy Denoyette [MVP]

You need to regasm the dll on the target system. You should also not install this in a
private folder not in a system folder like System32, use the "/codebase " option when
running regasm or register the dll in the GAC if you need this server to be accessible
from multiple clients.

Willy.


Oh, and make sure you don't need other dependencies on the target machine. Or - the joy of
posting dummy code.

Willy.
 
A

Armin Zingler

Tremendo said:
Hi,

I have two PCs:
PC1: Visual Studio 2005 (including .NET framework 2.0.
PC2: Visual Studio 6 (using Visual Basic 6) + .NET framework 2.0
installed separately.

On PC1 I wrote and built a C# DLL (see code below), and created one
.tlb and one .reg file to expose its methods to COM.

On PC2 I copied the .dll, .tlb and .reg into WINDOWS\system32, and
executed the .reg to insert new entries to the registry. In Visual
Basic 6, I created a new project, and added a reference to the .tlb.
So far, everything seems to be ok. I can see the class in the object
inspector, and browse its methods and enumerations. Also, the tool
that shows as I type the valid methods and parameters works ok.
Compilation to exe works fine. Problems start at run time. Just
trying to instantiate one instance of the COM exposed class gives me
a "Run-time error '-2147024894 (80070002) Automation error'". See
VB6 code below, too. Both listings have dummy code.

Any hint about what can this be due to?

I don't know whether the .reg file is a replacement, but I usually only
deploy the DLL, then use regasm.exe /tlb to register the files on the client
machine and to have the tlb file created.

Armin
PS: I don't see the relation to VB.Net.
 
T

Tremendo

I don't know whether the .reg file is a replacement, but I usually only
deploy the DLL, then use regasm.exe /tlb to register the files on the client
machine and to have the tlb file created.

Armin
PS: I don't see the relation to VB.Net.

(You are right, I posted in VB.net instead of plain VB. Sorry)

Hi,

I tried what you said (using "regasm xx.dll /tlb"). I noticed a slight improvement, in the sense
that now, in VB6, when adding a reference to the COM object, I do see an entry named
"Prod_CC1100_Test" in the list of possible things to reference to. Before, I needed to click on
"browse" and look for the .tlb. Other than that, I see no other differences. I still see my class
and its methods with the object inspector, but I continue getting the same automation error :-(

Some possibly helpful info:
- On PC2, I did not unregister what the execution of the .reg had caused. I used the same GUIDs
(hoping that I would end up overwriting the same entries in the registry), built the DLL on PC1,
copied only the .dll to C:\xxx\dll\Prod_CC1100_Test.dll on PC2, run there the "regasm xx.dll /tlb"
(it said everything went ok) and started a fresh VB6 project.
- I corrected the name C_Proc_CC1100_Test (which was screwed up) to C_Prod_CC1100.
- On PC2 (with Windows XP), the installations of .NET Framework 2.0 and Visual Studio 6.0 are both
fresh.
- The VB6 project does not need to reference anything else. I list some code below, exactly as it
shows up.

I see, in the .vbp file, some reference to stdole2.tlb, which I'm not using, at least intentionally.
I also see another line in the same file mentioning "Automation", which seems to be related to the
error.

Any more hints?

Thanks a lot,
Tremendo



%%%%%%%%%%%%%%%%%%%%%%%%
Contents of Form1.frm
%%%%%%%%%%%%%%%%%%%%%%%%

VERSION 5.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 3090
ClientLeft = 60
ClientTop = 450
ClientWidth = 4680
LinkTopic = "Form1"
ScaleHeight = 3090
ScaleWidth = 4680
StartUpPosition = 3 'Windows Default
Begin VB.CommandButton Command1
Caption = "Command1"
Height = 975
Left = 240
TabIndex = 0
Top = 240
Width = 1095
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub Command1_Click()
Dim JCMLib As C_Prod_CC1100_Test
Set JCMLib = New C_Prod_CC1100_Test
End Sub

%%%%%%%%%%%%%%%%%%%%%%%%
Contents of Proyecto1.vbp
%%%%%%%%%%%%%%%%%%%%%%%%

Type=Exe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\WINDOWS\system32\stdole2.tlb#OLE
Automation
Reference=*\G{D06A2026-F1D6-454E-BE4C-D4CCD41CC861}#1.0#0#..\dll\Prod_CC1100_Test.tlb#Prod_CC1100_Test
Form=Form1.frm
Startup="Form1"
Command32=""
Name="Proyecto1"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="JCM"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1

[MS Transaction Server]
AutoRefresh=1

%%%%%%%%%%%%%%%%%%%%%%%%
 
T

Tremendo

You need to regasm the dll on the target system. You should also not install this in a

I guess you meant "You should also install", right? I assumed that, and installed the dll in a
private folder, as you can read in my other post.
private folder not in a system folder like System32, use the "/codebase " option when
running regasm or register the dll in the GAC if you need this server to be accessible from
multiple clients.

Ok, this seems to work. I run "regasm Prod_CC1100_Test.dll /codebase /tlb", and it works for me. It
seems to need the "/codebase" option.

I didn't need to do anything with the GAC. Only one client will need to access that COM object (is
that the name?).

Thank you very much!
 
W

Willy Denoyette [MVP]

Tremendo said:
I guess you meant "You should also install", right? I assumed that, and installed the dll
in a
private folder, as you can read in my other post.
Yep, that's what I meant.
Ok, this seems to work. I run "regasm Prod_CC1100_Test.dll /codebase /tlb", and it works
for me. It
seems to need the "/codebase" option.

The codebase option is all you need, just make sure you got your assembly signed.
I didn't need to do anything with the GAC. Only one client will need to access that COM
object (is
that the name?).
Multiple native COM clients can acces that COM server without the need to install it in the
GAC. The GAC is only required if you have multiple managed clients (or a mix of
native/managed) accessing the assembly.

Willy.
 
Top