Adding a reference to a DLL, while keeping it a native DLL instead of an ActiveX Control - dll

I'm forced to use a third-party COM component in an application, and I'm having issues adding the reference to my project.
I've added this DLL as a reference to a project before, but in the past it would link directly to the DLL, such that the "Path" in the reference's properties would be filesystem path where the DLL was installed (i.e. not relative to my solution's directory). However, now, when I add the reference, the "Path" is to my project's obj directory, "Embed Interop Types" is set to True, and it's listed as an ActiveX component (which is not correct).
Then, I stumbled upon this MSDN article, which says:
If you want to add a reference to a registered COM DLL that contains an internal manifest, unregister the DLL first. Otherwise, Visual Studio adds the assembly reference as an ActiveX Control instead of as a native DLL.
Well, there you have it. That's my exact problem. I need the native DLL, but I'm getting an ActiveX Control instead. So, I did as it suggested and unregistered the DLL. However, when I then try to add the reference, I get an error saying:
A reference to ... could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
If I register the DLL again, I'm able to add it as a reference, but again, it's added as an ActiveX control. At this point, I don't know what else to do. Microsoft is very clear that I must unregister it before adding it as a reference, but then Visual Studio 2013 apparently won't let me add an unregistered DLL. Any one have any idea how to work around this?
UPDATE
So, apparently a recent update to this app made COM the only option (no directly using the DLL). The fact that it was added as ActiveX didn't mean anything. The problem turned out to be that this was a 32-bit library trying to run in 64-bits. I knew that was a potential problem, but switching the platform target to x86, still resulted in an error so I ended up chasing a red herring. Turns out IIS Express 8 runs natively as 64-bits even if the platform target of the site you're debugging is 32-bit. I had to go into Visual Studio options and uncheck the flag that tells IIS Express to run 64-bit (under "Web Projects") and then everything ran fine.

So, since adding the registered DLL was pretty much a no-go, I focused instead on trying to figure out why Visual Studio wouldn't let me add it when it was unregistered. I mean, sure, I might get an error about it being an unregistered DLL once I tried to run the project, but it should at least let me add it as a reference, regardless.
I eventually stumbled upon tlbimp.exe, which according to Microsoft:
The Type Library Importer converts the type definitions found within a COM type library into equivalent definitions in a common language runtime assembly. The output of Tlbimp.exe is a binary file (an assembly) that contains runtime metadata for the types defined within the original type library.
Okay. Well anyways, I opened a Visual Studio Developer Prompt (regular cmd doesn't have tlbimp.exe on the path), and ran my DLL through it. It created a new DLL, which I was able to add as a reference, and it satisfied my project dependencies. However, I haven't tested it just yet to make sure everything still works as it should once this thing is running, so I'll update with what I find there.
UPDATE
Yeah, so this doesn't work either. I get the same error once it's running saying that the class is not registered. Only now, I can't register this DLL because tlbimp.exe removes the entry-point.

Related

How to build a project that relies on a third party COM library on a build server?

I have a project that I am developing that uses a third party COM library as a reference and I would like to build this project on a Visual Studio Team Services build client. My first idea is to create a MSBuild task that checks to see if the COM library is installed on the local computer and if it is not, go ahead and install it, but this seems like a really messy way to do this. I have searched around but it seems as though all the answers date back years and I can't seem to make the few I have found work in a VS 2013 project. How have other people solved this problem? Is there a cleaner way?
For reference I have also tried this solution, which looks really clean, to no avail.
I would go one of these routes:
Generate interop dll with tlbimp, add it to your project and reference it directly:
In VS command prompt, execute tlbimp.exe <your_dll> to generate the interop dll. You can specify the name with /out option.
put this dll somewhere with your code
reference it by going to Add reference > Browse and click Browse... to add the dll
Generate the tlb from COM dll , add it to the project and reference the tlb:
Generate the tlb (e.g. using OLE/COM Object viewer) or extract it from the dll resources,
put this tlb somewhere with your code
reference it by going to Add reference > COM and click Browse... to add the tlb reference to project
As #HansPassant noted in comments, this solution still relies on registry, but you can register it with regtlb, regtlib or similar tool, as a prebuild step, which should be easier than installing the server (though if it is just a dll, you could use regsvr32 to register it instead of full install). However, this is still more complex than the approach with interop dll

VB6 compile against side-by-side assembly

I have a DLL written in C# and set for COM visibility. I have it setup as a side-by-side assembly and can successfully deploy the application to client PCs registration free. My question is related to the development PC. Is it possible to compile against the DLL in a similar registration-free manner or is registration required on the development machine? I have tried adding the DLL directly though the Project -> References menu and get an error stating "Can't add a reference to the specific file." The DLL is sitting in the same directory as the .vbp file and I have tried adding the DLL both with and without the client app manifest being present.
I have tried adding the DLL directly though the Project -> References menu
That adds a reference to a type library. A type library is a language-independent description of the types in a COM component, VB6 uses it to know how generate efficient code and to provide type checking and auto-completion. A type library is the exact equivalent of metadata in a .NET assembly.
Traditionally, and the way VB6 did it, the type library was embedded as a resource in a DLL. So you are probably used to picking a DLL in the dialog. That however doesn't work so well when the DLL is generated by C#, the type library can only be generated after the C# code is compiled. You have to pick the .tlb file in the VB6 dialog. The traditional way starts with the COM component being described in the IDL language, the type library can be generated before the code is compiled so can easily be embedded in the final DLL. It is technically possible to do it in C# as well, but the build steps are very laborious and painful, you essentially have to build the DLL twice with different build commands.
The type library for a C# library is normally generated in one of three ways:
Using Project + Properties, Build tab, "Register for COM interop" option. This requires VS to run elevated so it can write to the registry. You start VS elevated by right-clicking its shortcut and picking "Run as Administrator"
By running Regasm.exe, using the /tlb:filename option. An alternative for the 1st bullet and necessary if you don't want to run VS elevated for some reason. Using the /codebase option on your dev machine is also wise to make it work exactly like the 1st bullet and not require putting the DLL into the GAC with gacutil.exe
By running the Tlbexp.exe utility, the type library exporter for .NET assemblies. No registration is done, it only generates the .tlb file.
The first bullet is the normal choice and very desirable because you can never forget to update the type library this way. It is perfectly fine on a dev machine since you only really care about reg-free deployment on the user's machine. You probably got into trouble by not doing this anymore.
Using the 3rd choice is okay and more compatible with your goals, run Tlbexp from the Visual Studio Command Prompt. Just keep in mind that you have to do it again when you make changes to your C# code. Forgetting this once and losing clumps of head-hair trying to figure out why your C# changes don't seem to be effective or getting hard-to-diagnose error codes gives you lots of reasons to consider the 1st bullet again :) You can emulate the reg-free scenario by running Regasm.exe with the /uninstall option.

Can't build UserControls under x64

I am trying to troubleshoot a VB.NET project that contains UserControls (actually, several of them that are displaying the same issues). I am trying to get them to build under x64, but it is impossible. In x86 or AnyCPU, the UserControl builds and shows up in the Toolbox, so I can add or modify it in the forms that require it. In x64, the controls disappear from the Toolbox, I get warnings during build (the current project builds though), I can't see any of the forms - I get errors (please see below) - and projects that require the project with the form as an import will not build.
When I was studying what these UserControls are so that I can maybe rebuild them from scratch, I downloaded code from a book - great learning tool, but I get the same errors:
Could not find type 'Chap15SampleCode.ListSelector'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built using settings for your current platform or Any CPU.
The variable 'ListSelector1' is either undeclared or was never assigned.
I also get warnings, not sure what to do about them:
Possible problem detected while building assembly 'Chap15SampleCode': Referenced assembly 'mscorlib.dll' targets a different processor
Possible problem detected while building assembly 'Chap15SampleCode': Referenced assembly 'System.Data.dll' targets a different processor
I checked and found System.Data as a Reference is in c:\Windows\Microsoft.NET\Framework... (if I change the target framework to 4.0 the Reference is in c:\ProgramFiles(x86)... that was what my projects had ... and I tried to change it because of the x86, I couldn't, I had a few others in ProgramFiles(x86) and I thought that may be the problem ?)
Reinstalled VS2010, reinstalled Windows - did the same before btw - but I do have a clean system so I can't blame it.
If I can get this simple project to work, I hope the real projects will be easy - Please help me figure out what this is about. Thank you.
You have changed the Platform target setting in the project to x64. This is not appropriate for any project that produces a DLL. The actual bitness of a process that uses your DLL is determined by the EXE that starts the process. Or the host in which your DLL runs, the case for Visual Studio which is a 32-bit process. There is nothing a DLL can do to force the bitness, it can only refuse to get loaded. Which is what you see happening.
Change the setting back to AnyCPU so that your UserControl will work correctly in any process, regardless of its bitness. Including the VS designer. Project + Properties, Build tab. For VB.NET it is located in the Compile tab, Advanced Compile Options button.

error "429" AcitveX Component Can't create object (in vb6)

I have one problem in vb6. I created a .tlb file in VB.net 2005 by adding Com class to project. I built the project, I got .tlb file and .dll files while building project, i selected "Register for Com interop" from project properties and built. It registered autometically and I can use created .tlb file in that PC in Vb6 working fine. if I deploy application to another PC and run I am getting "Error 429 ActiveX Component Can't create object" run time error. What I need to do? Please help me as soon as possible. I can't deploy the application to client due to above error.
one possible solution is to install .net frame work on client pc i never want to install .net framework any other solution will be most appreciatable.
If you've created a DLL in a .NET language (such as VB.NET), the target computer must have the .NET Framework installed in order to use the DLL.
This a hard and fast requirement, irrelevant of how you're utilizing the DLL, whether from a VB 6 application through COM interop or otherwise. It is also a hurdle you'll have to jump over first, before you worry about things like registering COM components, as Uday's answer suggests.
If you don't want a dependency on .NET, you need to use another environment to create the ActiveX DLL; either C++ or VB 6 are possible choices.
One option may be that, while deployment, you need to register that .tlb file in System Registry using regsvr32 command in command-prompt. Generally static libraries does not work until they are registered with System Registry.
You might have seen many programs register components during installation like 'Registering Type Components' or 'Registering COM Components' (for those who do networking especially). Those components are nothing but native COM dlls and tlbs.
so when creating deployment project, add some scripting login to register thode dlls and tlb to System registry using:
regsvr32 <path to tlb/dll>
you have to recursivey call this command for every dll/tlb you want to register with system. For example, if you have 4 dlls and 2 tlbs then you have to call it 6 times providing the path of dll and tlb one at a time.

Problems adding a COM component reference to a VB.NET project

I have a third party COM dll that I'm trying to add to a vb.net (2008 express) project. I put the dll in C:\WINDOWS\system32\ and registered it with "regsvr32 vxncom.dll". When I go to projects > add reference and go to the COM tab it shows up in the list of available components/libraries. But, when I select the library and hit ok, visual studio complains: "A reference to 'vxncom 4.0 Library' could not be added. Could not register the ActiveX type library 'C:\WINDOWS\system32\vxncom.dll'."
The project I am doing this in is an example provided by the folks who distribute the dll. The component also fails to be added when I start a new (blank) vb.net project.
UPDATE 1:
I ran dependency walker on the dll in question and here's what I got in the error log:
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
The module in question seems to be libeay32.dll, but it already exists in C:\WINDOWS\system32.
UPDATE 2:
I went to the openssl site and downloaded and used their installer to update the libeay32.dll. I ran dependency walker again on vxncom.dll, and there were no errors. Went back to visual studio and it still didn't want to add the reference. Exact same error as before.
Maybe the DLL VB is trying to register depends on another DLL that is not present. You can confirm this (or rule it out) by using the free Dependency Walker tool from http://www.dependencywalker.com/
RESPONSE TO UPDATE 1:
Sounds like there's a mismatch between the version of libeay32.dll that's installed on your system and the one that your component is expecting -- depends is saying that your component is looking for a function that isn't there. I would check the version number of libeay32 and then contact the vendor and ask them what versions they support.
Just a thought - you may get a more detailed error message if you create your own PIA using tlbimp.exe, rather than relying on the IDE to do it for you.
Assuming you haven't fixed it or have moved on to alternatives; and following on from jeffm's answer is libeay32.dll properly registered with the operating system? Re-installing / repairing usually fixes that type of problem (I see it a lot with MS Office and MapPoint where the COM objects occasionally unregister themselves for one reason or another.)