Automation
-
I used an ActiveX Object in my VB6 project like this: obj = CreateObject("AAA.BBB"); When I tried to do the same thing in C# .Net project, I can't not find this object in "Add reference" dialog. Does anyone know why? Thanks in advance!
-
I used an ActiveX Object in my VB6 project like this: obj = CreateObject("AAA.BBB"); When I tried to do the same thing in C# .Net project, I can't not find this object in "Add reference" dialog. Does anyone know why? Thanks in advance!
When you add an assembly reference (an interop assembly is created automatically for COM libraries), you must know in which library the COM object is contained. To generate an ActiveX wrapper (known as a Runtime Callable Wrapper, or RCW) for this specific object, right-click on the toolbox and select Customize (or similar). Click the COM tab and find the control you're looking for. This generates a wrapper, which you can then use the
new
operator to instantiate. The typelib for that ActiveX control is converted to an interop assembly and automatically added to your project references. .NET isn't VB6 - far from it. It's a type-safe runtime that manages memory and provides code access security, among many other things. For more information on COM interoperability in .NET, see Interoperating with Unmanaged Code[^] in the .NET Framework SDK on MSDN Online, specifically the section Exposing COM Components to the .NET Framework[^].Microsoft MVP, Visual C# My Articles
-
When you add an assembly reference (an interop assembly is created automatically for COM libraries), you must know in which library the COM object is contained. To generate an ActiveX wrapper (known as a Runtime Callable Wrapper, or RCW) for this specific object, right-click on the toolbox and select Customize (or similar). Click the COM tab and find the control you're looking for. This generates a wrapper, which you can then use the
new
operator to instantiate. The typelib for that ActiveX control is converted to an interop assembly and automatically added to your project references. .NET isn't VB6 - far from it. It's a type-safe runtime that manages memory and provides code access security, among many other things. For more information on COM interoperability in .NET, see Interoperating with Unmanaged Code[^] in the .NET Framework SDK on MSDN Online, specifically the section Exposing COM Components to the .NET Framework[^].Microsoft MVP, Visual C# My Articles
Thank you both very much, this is very helpful. However I don't know which com dll I am using. Because this com dll is not provided for development purpose. It's registered by installing a specific software. I just happen to know this back door. When I tried to find the same com in the COM tab in VS.Net, I can not find it. Then I went to my registry table, it didn't tell me which dll it's, it just showed like this under the CLSID folder: 'C:\program files\AAA\aaa.exe Automation'. According to my understanding, VS.Net should be able to pick up the registered COM and show them in the COM tab. Now I don't understand why in VB6 it is ok, but doesn't work in VS.Net. Is it because this COM doesn't register correctly? Thanks in advance!
-
Thank you both very much, this is very helpful. However I don't know which com dll I am using. Because this com dll is not provided for development purpose. It's registered by installing a specific software. I just happen to know this back door. When I tried to find the same com in the COM tab in VS.Net, I can not find it. Then I went to my registry table, it didn't tell me which dll it's, it just showed like this under the CLSID folder: 'C:\program files\AAA\aaa.exe Automation'. According to my understanding, VS.Net should be able to pick up the registered COM and show them in the COM tab. Now I don't understand why in VB6 it is ok, but doesn't work in VS.Net. Is it because this COM doesn't register correctly? Thanks in advance!
That's a not a back door. Going into your registry and finding out which executable contains the component is what COM does anyway. That's how it works. It appears that this COM component you want is actually an out-of-proc automation server. You should still have no problems using it, but you first need to use the write "COM tab", or just create it manually using tlbimp.exe. If you're looking to add a COM component, you need to use the toolbox customization dialog, not the project references dialog. That would be to add an entire typelib. It would help if you knew where the typelib for this automation server is located. Sometimes they are embedded in the executable itself, and sometimes they are external files. You can easily use tlbimp.exe on that to create an interop assembly. You should also read the links I gave you. Again, .NET is not VB6 and works a little differently under the covers when dealing with COM.
Microsoft MVP, Visual C# My Articles
-
That's a not a back door. Going into your registry and finding out which executable contains the component is what COM does anyway. That's how it works. It appears that this COM component you want is actually an out-of-proc automation server. You should still have no problems using it, but you first need to use the write "COM tab", or just create it manually using tlbimp.exe. If you're looking to add a COM component, you need to use the toolbox customization dialog, not the project references dialog. That would be to add an entire typelib. It would help if you knew where the typelib for this automation server is located. Sometimes they are embedded in the executable itself, and sometimes they are external files. You can easily use tlbimp.exe on that to create an interop assembly. You should also read the links I gave you. Again, .NET is not VB6 and works a little differently under the covers when dealing with COM.
Microsoft MVP, Visual C# My Articles
Thanks again! I work it out with your help. It's a late-binding COM. However another thing is I found late-binding in VS.Net is a bit more complicated than in VB6. In VB6:
if com_obj.State.Result = com_obj.SUCCESS then .....
But In C#.Net, I have to do this:object success = t.InvokeMember("SUCCESS", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, com_obj, null); object state = t.InvokeMember("State", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, com_obj, null); object result = result.GetType().InvokeMember("Result", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, state, null); if ( state.Equals(success) ) ....
Is it there any more convenient way in VS.Net to do the same thing? Thanks in advance! -
Thanks again! I work it out with your help. It's a late-binding COM. However another thing is I found late-binding in VS.Net is a bit more complicated than in VB6. In VB6:
if com_obj.State.Result = com_obj.SUCCESS then .....
But In C#.Net, I have to do this:object success = t.InvokeMember("SUCCESS", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, com_obj, null); object state = t.InvokeMember("State", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, com_obj, null); object result = result.GetType().InvokeMember("Result", BindingFlags.Public |BindingFlags.GetProperty | BindingFlags.GetField, null, state, null); if ( state.Equals(success) ) ....
Is it there any more convenient way in VS.Net to do the same thing? Thanks in advance!Because of the fundamental architecture of COM and .NET interoperability. The code you're doing is essentially what the VB virtual machine does in the background using the
IDispatch
implementation of automation classes (it finds the method by the DISPID and invokes it with the specified parameters). You shouldn't have to do this, though. If you create your interop assembly correctly, you just use the classes and methods from that. That's what the interop assembly is for - wrapping the COM control in a runtime-callable wrapper (RCW). Again, read that link about exposing COM components to the .NET Framework I posted before. It's important to truly understand and not just accept the first thing that works. If you keep doing what you're doing, it'll take you forever to finish! Do it right and create and use the interop assembly.Microsoft MVP, Visual C# My Articles