|
-
Aug 3rd, 2013, 01:42 PM
#1
VB6 with DLL
Does VB6 register your DLLs?
I have read where DLLs need to be registered however I have several VB6 applications that uses custom DLLs (DLLs I made using C) that I include in the App.Path. Applications work just fine and yet I did not register any of these DLLs
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Aug 3rd, 2013, 05:04 PM
#2
Re: VB6 with DLL
 Originally Posted by jmsrickland
Does VB6 register your DLLs?
Only ActiveX ones.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Aug 3rd, 2013, 06:16 PM
#3
Re: VB6 with DLL
So this means that as long as the DLL (not ActiveX but regular ones) is in the App directory I don't have to register it
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Aug 4th, 2013, 05:07 AM
#4
Re: VB6 with DLL
 Originally Posted by jmsrickland
So this means that as long as the DLL (not ActiveX but regular ones) is in the App directory I don't have to register it
Aside from, that you will never have to "register" a regular Dll (since it does "by definition" not contain a COM-TypeLib) -
your assumption is correct as far as: will my compiled executable "see" this Dll and automatically load it? -> yes, it will.
The topic (since we talk about "regular-Dlls") is related to the 'delayed loading' VB performs at the first occasion it stumbles over a Line-of-Code where you make use of a "Function you wrote a Declare for".
In case the Function-Pointer for this function was not yet resolved - VB then automatically (under the covers) starts its attempts to retrieve it (per GetProcAddress) and cache it for the next attempt -
but for GetProcAddress to succeed we need a valid LibraryHandle for the Dll in question ( the DllName you specifiedin the Lib "..." section of a Declare).
So in case VB also has not yet cached the Library-Handle - it will have to perform this step now too, (before the GetProcAddress call can take place).
And the underlying WinAPIs for Dll-Loading are the LoadLibrary/LoadLibraryEx-calls - please read what the MSDN states for the LoadLibrary-API and how paths are resolved (in what order).
But basically yes, the App.Path is a good place to put "App-private Dll-functionality into" when you deploy.
There's "an issue" which sometimes pops up when you develop in the IDE (in case the CurrentDir was shifted away) - and that is:
The App.Path (in IDE-mode) resolves always to "where your current *.vbp is located".
But LoadLibrary searches in the *Process'* App.Path first for Dlls which are not already loaded - and the hosting process when you run your project in the IDE is VB6.exe -
and thus the LoadLibrary-call will search not the "App.Path" where you *.vbp is located for the Dll, but in the Directory where VB6.exe was installed.
Just keep that in mind to avoid surprises.
In summary - no problem at all with:
SomePath\
....MyApp.exe
....MyRegularHelper.dll
Potential problems with:
SomeSrcPath\
....MyApp.vbp
....MyApp.frm
....MyRegularHelper.dll
For the latter case there are different workarounds (either place MyRegularHelper.dll on your dev-machine also in \System32 - or alternatively in your path where VB6.exe resides) -
or just use a "preloading of the Dll by hand" directly in your Source-Project on App-Startup when you run in the IDE:
Sub Main()
If InIde Then LoadLibrary App.Path & "\MyRegularHelper.dll"
End Sub
Olaf
Last edited by Schmidt; Aug 4th, 2013 at 05:11 AM.
-
Aug 4th, 2013, 06:36 PM
#5
Re: VB6 with DLL
Speaking of ActiveX DLLs and OCXs, I consider this a poor practice generally.
Say you write a program X.EXE that uses A.DLL that you write. You drop X.EXE and A.DLL into a folder on some other PC. Run X.EXE and A.DLL gets registered in place. All is well.
Now you write Y.EXE that also uses A.DLL, drop them both in another folder on that other PC. Run Y.EXE and again everything works fine.
Delete the folder with X.EXE along with the first copy of A.DLL, run Y.EXE and... kaboom.
I'm not sure this even works at all for DLLs that only contain classes. It may only work for OCXs (or DLLs with controls defined in them). An OCX and a DLL are the same thing, it's just a naming convention.
It is far better to put ActiveX DLLs and OCXs either (a.) where the vendor has defined them to go, generally System32 for Microsoft libraries or Program Files\Common Files\xxx - or else (b.) in a subdirectory under App.Path so "magic registration" never occurs and you are force to create and use proper installers. If you write a shared library you are the "vendor" so you need to target a Common Files subfolder.
If you "made a DLL in C" then these registration issues don't apply.
-
Aug 4th, 2013, 07:41 PM
#6
Re: VB6 with DLL
 Originally Posted by dilettante
Speaking of ActiveX DLLs and OCXs, I consider this a poor practice generally.
Direct App.Path-placement is definitely bad practise in case of OCXes (or Dlls which contain Usercontrols... yes), since an upstarting VB-Standard-Exe will try an automatic registration of its internally referenced OCXes
(never tested ActiveX.exes in this regard - and can only guess that those executables will also make such a "Control-found-In-App-Path...let's-register-it"-attempt).
Those registration-attempts (last time I tested with VB6/SP5 some years ago) were never tried in case of "normal ActiveX-Dlls" (those Dlls which did not contain any Public UserControls).
Worth mentioning maybe: since the times of "UAC-managed-systems" those registration-attempts will usually fail, in case the Exe runs normally ("non-elevated").
 Originally Posted by dilettante
It is far better to put ActiveX DLLs and OCXs either (a.) where the vendor has defined them to go, generally System32 for Microsoft libraries or Program Files\Common Files\xxx -
Sure, "commonly used 3rd-party OCXes or Dlls" are better placed in the appropriate "common- or system folders" (by Setup-programs which do a decent version-check in case a similar Binary is "already there").
 Originally Posted by dilettante
or else (b.) in a subdirectory under App.Path so "magic registration" never occurs and you are force to create and use proper installers.
Yep - with a SubFolder one would avoid any of the potentially dangerous AutoRegistration-attempts of an upstarting VB-compiled Executable (in case of Control-Binaries).
Also worth mentioning in this regard and at this occasion (when such a SubFolder is used for ActiveX-Dlls) is the regfree approach which
works over my small (20KB or so) DirectCOM.dll - in this case no Setup would be required at all...
DirectCOM.dll is a regular StdDll which offers a GetInstance-API-call which allows (somewhat similar to CreateObject) the following regfree instantiation principle:
Set oSomeClassInstance = GetInstance(App.Path & "\Bin\MyAx.dll", "cMyClassType")
DirectCOM.dll is freeware and can be used also standalone (without the larger RC5-Framework-libs).
Since XP there's also the SxS-based regfree-mode over manifest-definitions - but I'm not very familiar with that approach -
maybe others can elaborate a bit, how this would work in conjunction with a "Bin-SubFolder" below the App.Path.
 Originally Posted by dilettante
If you "made a DLL in C" then these registration issues don't apply.
Yep - but good idea that you brought the topic of the ActiveX-binaries up - so we have everything covered nicely "in place" here I think... 
And as for placement of C-Dlls within the same Bin-SubFolder as the ActiveX ones...
Just perform a (one-time) LoadLibrary against the FullPath to your Bin-SubDirectory, to ensure that those libraries will be made available in the upstarting process as well:
Sub Main()
LoadLibrary App.Path & "\Bin\MyRegularStd.dll"
End Sub
Olaf
-
Aug 4th, 2013, 08:18 PM
#7
Re: VB6 with DLL
What is the difference between an ActiveX DLL and a normal DLL, what is activeX and why does it need to be registered?
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Aug 4th, 2013, 08:44 PM
#8
Re: VB6 with DLL
Simplified explanation:
ActiveX is the name that was given to Win32 OLE later on, though you'll still find both terms used all over the place.
ActiveX is based on COM, but is not strictly speaking COM itself. These are also often conflated but there are distinctions.
The registry comes in because ActiveX libraries are normally globally published through component registration. This deals with a huge number of topics but the basic idea is that a program can find and use "components" (controls and classes) and their type information without knowing what file implements them or where the file is. All the client program needs is a ProgID or ClassID, or in some cases a TypeLibID. Normally only a compiler needs the type library and you select these using the References and Components dialogs in VB6.
There are non-ActiveX libraries that use COM (lots of Win32 uses COM), and they don't need to be registered. The application is supposed to "know" the type information based on header files and such. These are hard to use in VB6 without a helper typelib, which would need to be registered.
There are "flat" DLLs that don't use COM at all. These are the ones you'd use via Declare Function statements in VB6. There are no classes, interfaces, etc. in them. A helper typelib can also be used with many of these DLLs for use in VB6, and once again it would need to be registered.
All of that ignores "reg-free COM" isolated assembly techniques, another topic entirely that adds some additional twists. Windows gained support for this with Windows XP in 2001. There are also a few ad hoc ways to load libraries registration-free. Some of those even work back as far as Win95.
One old article:
Simplify App Deployment with ClickOnce and Registration-Free COM
Last edited by dilettante; Aug 4th, 2013 at 08:50 PM.
-
Aug 4th, 2013, 08:57 PM
#9
Re: VB6 with DLL
 Originally Posted by Nightwalker83
What is the difference between an ActiveX DLL and a normal DLL, what is activeX and why does it need to be registered?
ActiveX DLLs are actually COM servers. They export services through interfaces. Now COM was meant to be a cure for DLL hell or some such thing. Weather it brought more problems than it solved is debatable, non-the-less, the approach they took was to require all COM classes(I believe co-classes is the correct technical jargon), interfaces and methods to all be identified by GUIDs to ensure uniqueness. This way you can have multiple versions of a single COM server existing side by side without problems because the COM clients would be bound against the IDs of whatever version it was compiled against. Every time you compile an ActiveX DLL, new IDs are generated for the interfaces, classes, and methods.
Now, all this information about the ActiveX DLLs interfaces is stored in something called a type library. They can either be embedded inside the DLL or separately in a .TLB file. Now when you register an ActiveX DLL, what happens is that the information about the classes and interfaces is written into the registry, otherwise COM clients would not be able to find them. When you compile a VB6 program that uses a COM interface like say, IPicture, its not actually binding to something called IPicture but rather an interface ID. The IID for IPicture is 7BF80980-BF32-101A-8BBB-00AA00300CAB. That is what your VB6 app looks for whenever you call on IPicture. That is how COM actually works. Using names is only a convenience for the programmer writing and/or using the interface. COM doesn't care about interface names, only IDs.
Another thing you should note is that typically registration is done by the ActiveX DLL itself. When you compile an ActiveX DLL in VB6 it actually exports two C style methods, DllRegisterServer and DllUnregisterServer. What actually happens when you call Regsvr32 on ActiveX DLLs is that it calls one of these functions depending on weather you're registering or unregistering it.
Last edited by Niya; Aug 4th, 2013 at 09:02 PM.
-
Aug 4th, 2013, 08:58 PM
#10
Re: VB6 with DLL
Damn....Dilettante beat me to it
-
Aug 4th, 2013, 09:07 PM
#11
Re: VB6 with DLL
 Originally Posted by Niya
Another thing you should note is that typically registration is done by the ActiveX DLL itself. When you compile an ActiveX DLL in VB6 it actually exports two C style methods, DllRegisterServer and DllUnregisterServer. What actually happens when you call Regsvr32 on ActiveX DLLs is that it calls one of these functions depending on weather you're registering or unregistering it.
Except that:
SelfReg Table
Remarks
Installation package authors are strongly advised against using self registration. Instead they should register modules by authoring one or more tables provided by the installer for this purpose. For more information, see Registry Tables Group. Many of the benefits of having a central installer service are lost with self registration because self-registration routines tend to hide critical configuration information. Reasons for avoiding self registration include:
- Rollback of an installation with self-registered modules cannot be safely done using DllUnregisterServer because there is no way of telling if the self-registered keys are used by another feature or application.
- The ability to use advertisement is reduced if Class or extension server registration is performed within self-registration routines.
- The installer automatically handles HKCR keys in the registry tables for both per-user or per-machine installations. DllRegisterServer routines currently do not support the notion of a per-user HKCR key.
- If multiple users are using a self-registered application on the same computer, each user must install the application the first time they run it. Otherwise the installer cannot easily determine that the proper HKCU registry keys exist.
- The DllRegisterServer can be denied access to network resources such as type libraries if a component is both specified as run-from-source and is listed in the SelfReg table. This can cause the installation of the component to fail to during an administrative installation.
- Self-registering DLLs are more susceptible to coding errors because the new code required for DllRegisterServer is commonly different for each DLL. Instead use the registry tables in the database to take advantage of existing code provided by the installer.
- Self-registering DLLs can sometimes link to auxiliary DLLs that are not present or are the wrong version. In contrast, the installer can register the DLLs using the registry tables with no dependency on the current state of the system.
For these reasons self registration (which is also what running regsvr32.exe does) has been considered very bad form for a long, long time.
-
Aug 4th, 2013, 09:45 PM
#12
Re: VB6 with DLL
Interesting. I've never run across that before. I've had quite a few ActiveX related problems in the past and I'm now wondering if that had something to do with it. I tend register a lot using Regsvr32 rather than rely on installers. I never knew that was frowned upon.
-
Aug 5th, 2013, 06:23 AM
#13
Re: VB6 with DLL
The issues have more to do with installers that update "usage counts" as you're supposed to rather than just registering in place. This can cause an uninstall to delete a shared library that is actually still in use.
Some of the other issues are more complex relating to the differences in registering per-user vs. per-machine, systems with multiple user profiles in use, interference with advertised and managed installs (like any MS Office install).
Doing component registration "correctly" can take some effort though. Some people will use RegMon, RegSpy, or similar tools to try to capture the basic registration done by running regsvr32, then edit the results for use in an installer.
Versions of Visual Studio sometime after 6.0 (maybe 8.0?) and before 2012 include the RegCap.exe utility which creates a captured .REG file without actually registering the target library, a less messy proposition. These VS products will use RegCap themselves durting installer project builds to help keep people from taking the "easy path" (self registration).
Other people have their own in-house utilities for this, WiX has its Heat.exe (the candle metaphor sure gets old!), and so on.
-
Aug 5th, 2013, 06:42 AM
#14
Re: VB6 with DLL
BTW:
For libraries shipped with VB6 you can use the VB6 SP6 Component Merge Modules in your Windows Installer projects. They contain the Registry Table entries required already.
Of course if you use VSI 1.1's "Simple VB6 Project" wizard you are back to square one with self registration again.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|