I am currently trying to reference a .NET COM library in my Visual Basic 6 application. I have registered it, using Regasm and I have set ComVisible to true within my class. However when I try to run my application i get the following error:
ActiveX component can't create object.
My library consists of a very simple function (since I just wanted to test if I could even run it), it just returns the string "Hello World".
I had to use a different machine (machine 1) to create my C# .Net class and then copy that class onto another machine (machine 2) and from there register the dll and reference it in my project. I then tested my project on a separate machine (machine 3) which is were I received the error.
I really need help with this, I have already tried to un-register and re-register it and still to no avail.
Try this.
From an elevated command prompt:
RegAsm /codebase /tlb AssemblyName.dll. Take note of the .tlb file generated.
RegTlib File.tlb
Open your VB6 project and reference the .tlb file.
Related
I have an activeX DLL in VB6 , and i've been asked to run some tests with it. since i dont have VB6 environment anymore, i thought it'll be best to try and make a simple C# program that will call the registered COM Dll. to do that i copied the DLL into c:\windows\system32, used regsrv32 to register the DLL, restarted the computer and this DLL is added to COM so I added it to my project and referenced to it from my project. I created an object from it and tried to invoke a function from that but there is nothing available but DllUnusedClass and DllUnused.
You say you've added a reference to the COM dll to your project, now I would right click on the reference and select "View in object browser". This will show you which types are available in the referenced dll.
It may be you're not creating the appropriate type of object, so viewing it in object browser should help you decide which type of object to create.
Make sure that any class you have in the VB6 project, that you want to access from your .Net application, has the Instancing property set to 6 - GlobalMultiUse so that it is in scope.
I have tested your scenario with the Instancing property set to the default 5 - MultiUse and experienced the same issue you described.
At work, we have a VB6 project (ActiveX DLL) that we need to be able to add as a reference to another VS2008 C# project.
A developer there tells me that in the past, they have been able to do so but now we made a change to the VB6 DLL and had to recompile it.
As such, we need to update the reference in the VS2008 project but when we try to add the reference to the VB6 DLL back (after removing the old reference) to the VS2008 project, we get a yellow "!" icon on the newly added reference and then when we build, VS2008 says the reference cannot be found.
I tried the "Browse" and "COM" tabs where you can add reference, no luck.
Do we need some kind of TLB to be able to add it or something ?
Thanks.
You need to do the following from a command prompt:
#CD to wherever the dll is located
regsrv32 /u foo.dll
regsrv32 foo.dll
This will unregister the old com object and register the new one.
He's right, you could do that from command prompt.
Remember though, your Active-X control DLL could be 16-bit, so use
regsrv /u foo.dll
regsrv foo.dll
from command prompt. But 32-bit works fine for regsrv32!
I used OLE/COM object viewer (included in Windows SDK 6.0A) then I saw a bunch of COM entries in "All objects" ie: MyDLLName.className and some were pointing to a DLL file which did not exist anymore. Deleted all the relevant COM entries in the Windows registry that pointed to the deleted DLL and left all the ones which pointed to the existing DLL and then I could import it successfully in my VC# project.
I've been trying to get a registration-free .NET based COM DLL to work, but without success.
In Visual Studio 2008 I added a new C# class library.
I enabled the 'make assembly COM-visible' and 'register for COM interop' options.
I added a public interface and class with some functions.
I added a manifest dependency to my C++ client application: #pragma comment(linker,"/manifestdependency ...
But when I start my application I get 'the application has failed to start because the application configuration is incorrect'.
I've used Microsoft's mt tool to extract the manifest files of both the C++ client application and the C# COM DLL and the information in both is the same (the dependentAssembly in the C++ manifest file contains the same name and version as the assemblyIdentity in the COM manifest file).
I've also tried the approach described on http://msdn.microsoft.com/en-us/library/eew13bza.aspx but with similar results.
Similarly I tried to add a reference to my COM project in 'Framework and References' of my C++ client application. The information on that property page looked promising (it shows options like 'copy local', 'copy dependencies', etc and properties like the 'assemblyIdentity'), but Visual Studio neither copies the DLLs nor adds a dependency to the manifest file automatically.
Note that the 'registered variant' works fine.
Anyone have any ideas of what I'm doing wrong?
Update:
When I create a simple C++ DLL and embed a manifest with the same name and version of my .NET COM DLL (same assemblyIdentity) my application starts up fine. So the problem lies with the manifest file of my .NET COM DLL.
I can successfully extract the manifest from the DLL with mt -managedassemblyname:... and then embed the same manifest with mt -outputresource:..., but this also doesn't cause Windows to successfully resolve the dependency.
I found the steps needed to get registration-free .NET COM interop working myself :-)
Run: mt -managedassemblyname:"myDll.dll" -out:"myDll.manifest"
Clean manifest (see format at http://msdn.microsoft.com/en-us/library/eew13bza.aspx). Mainly I needed to remove all tags except for assemblyIdentity, clrClass and file (and specifically remove the runtime, mvid and dependency tags).
Run mt -outputresource:"myDll.dll" -manifest "myDll.manifest". Basically this adds the modified manifest as a resource to the DLL. Note that this is apparently not the same manifest (location)! If I reextract the manifest with the managedassemblyname option I still get the 'old' manifest. If I extract it with the inputresource option I get the new one.
I pretty much found this all thanks to Windows Vista. Unlike my Windows XP it contains a tool called sxstrace that gives rather detailed information about the problems with side-by-side execution.
When I did this, I started with a very simple, basic component to get the COM stuff sorted. Also I used a script client in the initial development.
I did not use Visual Studio, but instead a text editor for the .NET code. I inserted the GUIDs for the assembly and for the Interfaces, and marked the interfaces for AutoDispatch.
using System;
using Interop=System.Runtime.InteropServices;
namespace Whatever
{
[Interop.Guid("xxxxxxxx-9120-4283-b972-changethis05")]
[Interop.ComVisible(true)]
[Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
public partial class MyClass :
...
}
I made sure my class had a default (no-arguments) constructor.
I ran regasm /codebase by hand, from the command line, specifying the .NET assembly.
I hand-coded the javascript to instantiate the object.
When things were confusing, I checked the ProgId with OleView.exe.
Once you have the very basic stuff working, add complexity gradually, until you get the working solution.
You can also use the approach from the other direction; from the client. .NET Assemblies like System.Random are marked for COM interop when you install .NET, so you can use them to verify that your approach in C++ is correct. Instantiating a System.Random ProgId is something like the "hello, World" of C++-to-.NET-via-COM. If that succeeds, then you know the basic approach in C++ is sound.
I just finished building my new COM project (C#, .NET 3.5). This project will be called by a VFP application. It's working great on my development machine, but now I need to know how to deploy it on the user's machine. Click Once isn't available for this kind of project, so I guess I'm stuck with manually distributing the DLL.
So, where should I put the DLL and how do I register it?
BTW, the 3.5 framework is already installed on the user's machine.
TIA
I've really never used RegSvr32 with .Net assemblies, rather I use the regasm with the /codebase option:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /codebase mydll.dll
You can also use the /tlb option to export the type library and register it.
Of course the easiest way, just create an installer with vstudio and it will do this for you.
Creating a Description of the COM class and Interfaces
.Net assemblies don't include information in Type Library compatible format. So it is necessary for the programmer to run one of two .Net-supplied utilities to extract the assembly description of a class into a Type Library file.
One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.
tlbexp ComServer.dll /out:ComServer.tlb
Assembly exported to C:\Magellan\Source\Output\Debug\ComServer.tlb
Once a Type Library has been created, it can be referenced by a COM client to obtain the information necessary for the COM client to bind to the interfaces of the COM class, and activate the COM class at runtime.
Registration of the COM Class and Interfaces
For a COM class to be accessible by the client at runtime, the COM infrastructure must know how to locate the code that implements the COM class. The following command accomplishes this:
regasm ComServer.dll
Your DLL can be put anywhere you wish, but a good choice is C:\Program Files\MyApplication.
http://www.csharphelp.com/archives/archive190.html
I am building a C# UI to interact with a COM Service (.exe). The VS2005 COM project outputs a valid typelib (TLB), which is referenced by the C# project. However, the VS2005 C# project insists that the service be registered in order to build the C# project, even though the typelib appears perfectly valid when examined with the OLE Object Viewer.
We would rather not register the service on the build server, if possible. Further, debug builds cannot register the COM object as a service, since this makes debugging in general, and startup code in particular, more difficult (can't use F5 - Start Debugging).
What should I look for in order to get this working? Do I need to register just the TypeLib? If so, why would COMInterop insist on having the service or TLB registered in order to build correctly (and, is there a command-line tool for this on Win2003 with VS2005)?
If I recall correctly, once apon a time I built a C# web service which referenced the Win2003 firewall COM object, but we built it on Win2000 (which does not have such a thing) simply by referencing the TLB file with no registration required, so I don't understand why this should be a problem now.
You need to create interop assembly using tlbimp.exe tool. And add reference to this assembly in your project instead of typelib. In this case building will not require registered com server.
If you do not want to ship yet another assembly, you can extract interface description from generated interop assembly using Reflector and include them into project as source files.
Solved this by adding a -regtypelib command to the COM service, which calls the AtlRegisterTypeLib function but does not register the service. Suboptimal because it will leave registery entries on the build server, but quick and it works.