createObject in VB6 does fails when running exe - vb6

I have a VB6 program which tries to run a DLL written in C#.
This DLL has a COM interface so I can create an object of a class in it with "CreateObject".
The problem is that it runs and works well when I run it from the VB6 IDE, but when I make an EXE and try to run it, it throws the exception:
"Automation error. The system cannot find the file specified (-2147024894)."
Why is it happening and how can i solve it?

Look at Project, References in the IDE and look which dll or ocx file belongs to the object you are referencing with CreateObject (the Object Manager might also help to find out).
This dll file must be available when the exe is compiled, too. Usually, you need to have it registered with regsvr32.exe.

A technique I use to figure issues of this type is to open the add reference dialog in Visual Basic 6. I scroll the list of available COM Libraries and see if the problem DLL is listed. If it is then CreateObject should work, you should be able to assign it do a variant variant and use late binding to access it's members.
In addition try temporally set a reference to the variable and instead of using CreateObject use the = New and see what error messages, if any, it gives you. Generally I found them to be more informative then the ones thrown by CreateObject.
Finally it would help if you post the reason why you are choosing to use CreateObject instead of setting of a reference. If the DLL is a known object that will be continually used by the program then a reference should be set and early binding generally used.
Finally it may be that the error is resulting from a dependency of the C# COM DLL not the DLL itself. If for example I was to take a Com Library and properly register it but it relies on the COM Library Widget2000 and it NOT registered then it will throw the automation error. Especially if you are testing the EXE in it's installed environment and not the environment in which you complied it.
For example suppose I have a CAD program written in VB6 and I have source tree that begins with MyCAD. THe exe is in MyCAD/MainEXE and the shape library is in MyCAD/ShapeLibrary. I run the IDE everything is fine. Then I make my setup and goto my test machine and install it and it error on the creation of shapelibrary.
The first thing I would do it check if MainEXE will run straight out of the MainEXE directory of my source tree. That test will eliminate whether it is a install issue or a quirk of the IDE vs complied version. Then I would look at the setup and see what not being registered. Also look at either the source for the C# library or the setup for the library and see what dependencies it needs. Since it a complied COM DLL you should be able to use a dependency walker tool to see what COM references it needs. Finally make sure the correct version of the .NET framework is installed.

If you are compiling the C# DLL on your test machine - make sure you have ticked the register for COM Interop setting. If you are not compiling on the same machine you need to run RegAsm with the /codebase option.

try compiling it as an installer and include the dll/com that you use in the compilation of the installer package so that the dll/com that you use will be include in the compilation of your exe.., and install it in the windows not just copy past it.

Related

QBSDK Distribution for VB6 App

Ok, I went through great lengths but I finally got my integration to quickbooks working on my VB6 application. It works perfectly on my build machine. I actually installed the qbdsk11 on my build machine and worte and tested the code. The ONLY new reference in the project is the QBFC11.dll.
So, I added the QBFC11.dll to my innosetup, told it to do a regsvr on the dll, and hoped this was enough.
NOT.
First, during install, I get a failure to register the dll. Apparently, this DLL isnt meant to be registered?
But the .DLL was put in Windows System32, so I tried my program anyways...
NOPE. Doesnt work. I get a runtime 91, about an object variable not set. Which makes sense, if it cant create the object.
So, for grins, I moved a copy of the .DLL into the program folder, next to my executable.
Same thing. Runtime error 91.
So, i then grab the whole qbsdk11 installer and install it on this machine. I figure I can make it an additional download for people who want to use this extra functionality.
But no, even with the whole SDK installed, I still get the same runtime error.
I have not been able to find any CLEAR information on how to proceed. I'd prefer for this to be part of my base install. But apparently something still just isn't right.
What did I miss? How do I fix this? I don't even know what to try next.
If you're using QBFC11, you must install the QBFC11 redistributable components with your application. You can find instructions on how to do this in the QBSDK Programmer's Guide in the section titled Redistributing SDK Components With Your Application, subsection Using Installers and Merge Modules.
The most likely cause of the runtime error you're currently getting is the manipulation of the QBFC11.DLL that you did before you installed the SDK. I would start again with a clean OS image so that you can get the proper procedure down.

Problems referencing com dlls in vs 2010

I'm running a 32 bit ver of win7 in a vm. I am trying to reference 5 com dlls (VB6) in my .net project. These dlls (and their dependencies) are registered ok since I can use them natively as they form a part of another app and that app is working fine.
I try to set a reference to any of them directly in vs and I get the error message - Library not registered (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED)).
However, if I set a reference to another com component (which I don't want to reference but which in turn does reference these libs) I find that the references to these com dlls (which I do want to reference) gets set correctly in vs. I then just need to remove the ref to the unwanted dll and everything seems to be good to go.
If I look at the GUID and version details of one of the successfully referenced component, they appear to be the same as the GUID and version that appears in the caption of the error form, when I unsuccessfully try and set a reference to the same component directly.
BTW I have tried repairing the VS installation to no avail
I was wondering if someone could explain what I am doing wrong.
EDIT: Follow-up following Hans suggestion
So I ran
tlbimp mylib.dll
and it returned a TI1006 error - Output would overwrite the input file. So following suggestions found, I then issued
tlbimp mylib.dll /OUT:interop.mylib.dll
and this then returned the error
TlbImp : warning TI3011 : Type library importer has encountered an interface not derived from IUnknown: '_HiddenInterface'. The interface is skipped.
TlbImp : error TI1033 : Cannot find type 'ADODB._Recordset_Deprecated' in 'ADODB, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. There could be a mismatch between the referenced assembly and the type library.
But I'm not sure if this is a red herring since this lib could be referenced when successfully referencing the different higher level dll. I have tried with a dll which doesn't reference ADODB and that seems to work using tlbimp. So, e.g.
tlbimp myNONADODBlib.dll /OUT:interop.myNONADODBlib.dll
works from the commandline. However
tlbimp myNONADODBlib.dll
still generates the error TI1006 - output file will overwrite input file, and I cannot reference this into my .net project
EDIT:
There seems to be a problem with ADO and Win7 SP1. http://support.microsoft.com/kb/2517589 which would account for the deprecated error message (TI1033) I was getting, but not why VS was failing to create a CCW for the dll I can manually create a CCW via tlbimp.
EDIT (12/03/28 10:40):
So I have rebuilt the com dll with the suggested tlb. I can now successfully run
tlbimp mylib.dll
without getting any error messages and it appears to complete successfully. However, when I try and add a reference to that dll in VS, I still get the same original error message ( Library not registered (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))). I have checked the registry and the registration looks ok i.e. it is pointing to the correct path - I'm wondering if it is a permissions-type issue - but I am running vs as admin.
EDIT (12/03/28 10:15):
So I ended up creating a new completely new vm with the same environment - and it worked ok. So I've no idea what is going on other than some registry corruption perhaps!
Many thx
Simon.
You need to use REGTLIB.exe to register the type library of the DLLs.
Type library registration is separate from component registration - the type library supports the introspection/type explorer functionality, and isn't usually required for running a precompiled application, though it may be required for compilation.

What is a Windows command-line EXE's "side-by-side configuration" and how do I correct it?

I have a simple .exe written in C++ (built with Visual Studio 2005) that tests some hardware using a supplied API. It works fine on the Windows 7 machine I built it on, but when I copy it to another (Windows 7) machine and run it (from the command-line) I get:
The application has failed to start
because its side-by-side configuration
is incorrect. Please see the
application event log or use the
command-line sxstrace.exe tool for
more detail.
What is "side-by-side configuration"?
I ran sxstrace.exe and read the usage info. It appears I would need to instrument my exe to generate a log file for sxstrace.exe to be useful?
I imagine the problem is my exe requires DLLs that either don't exist on the other machine, or are the wrong version. How do I find out what DLLs my exe uses, and what versions it links to on my machine (where it works)? Any other advice on copying it to another machine and getting it running? Would more information help?
mfawzymkh's answer to the "application has failed to start because the side by side configauration is incorrect" question (linked to in the question spirulence linked to in his answer to this question) appears to apply to this question also. mfawzymkh writes:
You can resolve this issue by either
one of these 1- Install VC8 Debug CRT
2- Build you app as statically linked
And mfawzymkh's comment on that same answer explains how to build as statically linked:
when you build it in VS, go to
projects->settings->C/C++->Code
Generation and choose Runtime Lib
options to be /MTd instead of /MDd
I did that and the side-by-side configuration message is gone. (And after installing something else for the DLL I was using, my EXE works.)
For what it's worth, I encountered the same issue. In the Event Viewer I had an error message that read:
Activation context generation failed for "C:\\MyExe.exe".Error in manifest or policy file "C:\\MyExe.exe.Config" on line 12. Invalid Xml syntax.
Sure enough, I'd changed a connection string and left out the closing quote. Added that back in and it solved the issue.
"when you build it in VS, go to projects->settings->C/C++->Code Generation and choose Runtime Lib options to be /MTd instead of /MDd" worked for me, although I was interested in the Release version instead of the Debug version.
Microsofto says:
/MT Causes your application to use the multithread, static version of the run-time library. Defines _MT and causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols.
/MD
Causes your application to use the multithread- and DLL-specific version of the run-time library. Defines _MT and _DLL and causes the compiler to place the library name MSVCRT.lib into the .obj file.
Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR100.DLL, which must be available at run time to applications linked with MSVCRT.lib.
Are you suffering from the same issue as this guy? Side-by-side assemblies, Windows 7, and Visual Studio 2005

How to fix "Unexpected error (32801)" when compiling VB 6 program?

I have to maintain an old VB 6 ActiveX DLL called by another third-party program for which I have no sources. This DLL works and compiles fine against the API of said program for about 6 years and 3 major versions.
But now when I try to compile the DLL against a new major version the mentioned error occurs. It seems the error occurs before "my" code is called so there´s no use debugging or logging. The only remedy was to compile w/o binary compatibility which is no real option. My Google search turned up quite some people with the same problem but no solution.
Does anybody here know how to fix this issue ?
I finally figure out how to diagnose VB6 error 32801 in a systemic way.
My theory is When the VB6 compiler is creating a project or binary compatible library, the compiler decompiles the type information from the referenced library. Error 32801 occurs the source code's type information is not the same as the referenced library.
There is a tool called OLEView. This tool can decompile the COM type information into an IDL text. What I do is decompile the referenced library in to IDL and take the last good build of the failing library. Most times it is a build server version but the build does not work on a developer workstation. Decompile the last good build. Use a text comparison tool, like WINMerge, and find the differences between the type libraries. The differences make it easy to track down the problem.
Depending on the difference will determine how to correct. Mitigation can be done by either correcting the reference DLL, or by source code correction, or source code references.
It sounds like one of the types in the interfaces defined in your new DLL is different from one in the previous DLL. I'm deducing you use types defined in the third party program in your public interfaces of your DLL. It sounds to me like the third party has changed the definition of one of the types but kept the name and GUIDs the same. You could use something like OLE/COM Object viewer to check whether that's true. If it is true then you can complain to the publisher of the 3rd party program. Do you have enough political power to succeed?
Bruce McKinney, the guru who wrote Hardcore Visual Basic 6, ran into the same issue with a structure in a type library, where he changed some of the member types. The only fix he could find was (essentially) to break binary compatibility - and that's after some correspondence with the VB6 compiler team, who he knew fairly well. I don't think anyone else could do better.
There is a discussion about this error on devx.com that seems to indicate that the problem stemmed from Microsoft's Scripting Runtime (scrrun.dll).
FileSystemObject compatibility Unexpected error (32810)
Does your DLL reference that library? If so, can you remove the reference (e.g., replace FileSystemObject functionality with intrinsic VB file handling functions and/or API calls).
Are any of the files associated with the core project being compiled marked as Read-Only (i.e. not checked out of SourceSafe or similar repository)?
*.exp
*.vbw
*.lib
---------------------------
Microsoft Visual Basic
---------------------------
Unexpected error (32810)
---------------------------
OK Помощ
---------------------------
This the message I was getting trying to reference in VBIDE an old OCX that has been recompiled recently.
After somewhat long research the offending lines of code causing this error appeared to be
Property Get MouseActivate() As BookmarkEnum
Just changed this to
Property Get MouseActivate() As Boolean
. . . and the error was gone.
BookmarkEnum is an enum from ADO. Our build server is Server 2003 and my dev machine is Win10. The project references ADO 2.8 but apparently this typelib has some differences on Server 2003 vs Win10

Strange VB6 build problems (related to nlog)

This I think is related to my use of the nlog C++ API (and my question on the nlog forum is here); the purpose of my asking this question here is to get a wider audience to my problem and perhaps to also get some more general ideas behind the VB6 IDE's failure to build in my particular scenario.
Briefly, the problem that I am having is that I am having trouble building VB6 components which reference unmanaged C++ components which have calls to nlog's C\C++ API (which is defined in NLogC.DLL). The build problems are not occurring during compile time, they are occurring when the binary is being built which suggests to me that it's some kind of linker type problem? Don't know enough about how VB6 binaries are produced to tell. The VB6 binary is produced, but it is corrupted and crashes shortly after it is invoked.
Has anyone had any similar experiences with VB6 (doesn't have to be related to nlog or C++)?
edit: Thanks for all the responses to this rather obscure problem. Still no headway unfortunately; my findings since I posted this:
'Tweaking' the compile options doesn't appear to help in this problem.
Adding a reference to the nlog-enabled C++ component from a 'blank' VB6 project doesn't crash it or cause weird build problems. So it isn't a 'native' VB6 issue, possibly an issue with the interaction between nlog and the various components and 3rd party libraries used by other referenced components?
As for C++ calling conventions: the nlog-enabled C++ component is - as far as I can see - compliant to these conventions and indeed works fine when referenced by VB6 as long as it is not making any nlog API calls. Not sure if the nlogc.DLL itself is VB6 compliant but I would have thought that that is immaterial since the API calls are being made from the C++ component; VB6 shouldn't know or care about what the C++ component is referencing (that's as far as my understanding on this goes...)
edit2: I should also note that the error message obtained during build is: "Errors during load. Please refer to "xxx" for details". When I bring up the log file, all that there is in there is: "Cannot load control xxx". Interestingly, all references to that particular control disappears from that particular project resulting in compile errors if I were to try to build again.
Got around the problem by using NLog's COM interface (NLog.ComInterop.DLL) from my unmanaged C++ code. Not as easy to do as the C\C++ API but at least it doesn't crash my VB6 components.
I would try tweaking some of the Compile options found in the Project, Properties menu, Compile panel to see if they yield any additional hints as to what is going wrong.
For example if you compile the executable to p-code rather than native code does it still crash on startup.
What error message do you get when you run your compiled binary?
I doubt the compiler/linker is the problem: project references in a VB6 project are not linked into the final executable. A project reference in VB6 is actually a reference to a COM type library (which may or may not be embedded in a .dll or other binary file type). Project references primarily serve two purposes:
The IDE extracts type information from the referenced type libraries which it then displays in the Object Browser (and in the Intellisense drop-down)
At compile-time, the compiler extracts the type information stored in the referenced libraries, including the CLSID of each class that you instantiate, and embeds this data into the executable. This allows your executable to create instances of classes contained in the libraries that you referenced.
Note that the compiled binary doesn't link to any code in the referenced libraries, and it doesn't even contain the filenames of the referenced libraries. The final executable only contains the CLSID's and other type information that it needs to instantiate COM objects at run-time.
It is much more likely that the issue is with NLog, or with how you are calling it from your code, rather than something gone awry in the VB6 compile process.
If you think it might be a linker problem, this should crash it the same way:
create a new standard project (of any kind)
add a new module and copy the "declare"-statements into it
compile
If it doesn't crash it is something else.
It would help an exact description of the error or a screenshot of what going on.
One thing to check is wherever NLogC.DLL or the C++ DLL you built have the correct calling convention defined. Basically you can't have the DLL function names mangled or use anything but the STDCALL calling convention. If the C++ DLL has not been created with those two things in mind then it will fail to work with VB6.
MSDN Article on Calling convention.
"Cannot load control xxx" errors can be caused by .oca files which were created from a different version of an .ocx than currently used. If that is the case, deleting the .oca files helps.

Resources