PDA

Click to See Complete Forum and Search --> : lost in .OCX registration hell


silverblatt
Apr 23rd, 2010, 03:26 PM
I develop and maintain several VB6 applications used internally by my employer. All PCs (both my development machine and the users' workstations) run Windows XP. My normal procedure is to develop and test the application, and build an installation package (using the Package and Deployment Wizard), on my machine, and then at each user's machine do the following:

1. log on using a domain administrator account
2. uninstall any previous version of the application
3. run the installation package to install the new version of the application
4. copy the Start menu entries and desktop shortcut to \Documents and Settings\All Users, so that the application can be run by any user
5. test the new version of the application to ensure proper operation

Recently, I completed, tested and built the installation package for version 2 of a particular application. One of the significant changes in this version is the removal of a listbox control and its replacement by an MS FlexGrid control (this was necessary because the users require different items to appear in different colors, which doesn't seem possible with an ordinary listbox). In order to use the FlexGrid, I had to add MSFLXGRD.OCX to the Components... list on the Projects menu. After upgrading the six existing users to version 2, and installing it for a new seventh user, I've run into a problem I've never seen before. When I log into any of the users' machines using the same domain administrator login that I used to install the application, it runs normally. But when I log out and the machine's user logs back in, when they launch the application it always aborts with the following error as soon as the form containing the FlexGrid is opened:

Run-time error '339':
Component 'MSFLXGRD.OCX' or one of its dependencies not correctly registered: a file is missing or invalid

With the machine's user logged in, I attempt to manually register the control by opening a command prompt window, making \Windows\System32 the current directory and entering regsvr32 msflxgrd.ocx at the prompt, but that always generates this error:

LoadLibrary("msflxgrd.ocx") failed - Access is denied.

Of course, if I then log out the user and log back in with the domain administrator login, I can successfully use regsvr32 to register and unregister the control, and the application runs normally for me. I'd always thought that component registrations were system-wide, but this situation seems to call that into question. I've read elsewhere that this problem can be resolved by registering the control in the HKeyCurrentUser section of the registry instead of (or in addition to) the HKeyLocalMachine section, and that I can do so by using a registry script rather than (or in addition to) regsvr32 and/or the installation package, but I have no idea of how to do so.

I'd be most grateful if anyone knows how to resolve this problem, as I've now got a bunch of users who are effectively locked out of their application. Thanks in advance.

dilettante
Apr 23rd, 2010, 06:17 PM
You're correct. Component registration changed after NT 4.0 (i.e. in NT 5.0, also known as Windows 2000).

I'd guess there could be a couple of things going on here:

Your setup may be copying the OCX onto the system in such a way that standard users do not have read & execute permissions to this file.
Your setup may be performing a per-user registration of this library instead of a per-machine registration.

From the symptoms I'd guess that the first is almost certainly true. The second might also be happening but most likely running regsvr32 logged on as such a user should then cure the problem (for that user).


You really never (never, never) want to use regsvr32 as any kind of deployment strategy. You probably should not be using the P&D Wizard or 3rd party tools like the Inno products either since they both typically do the same thing running regsvr32 does.

Running regsvr32 is really only useful for developers registering simple unlicensed libraries to be used for development. This should always be run by an admin (or maybe Power User if you're still on WinXP or earlier). Even then only count on the registration being available to that user.


But I think you also have a file security issue deploying MSFLXGRD.OCX or else running regsvr32 by the standard user should at least fix it for that one user.


It is getting tougher and tougher to support these old OSs like WinXP now. As this 9 year old OS fades into the rear-view mirror there is less authoritative information available about developing for and supporting XP.

Per-User COM Registrations and Elevated Processes with UAC on Windows Vista (http://blogs.msdn.com/cjacks/archive/2007/02/21/per-user-com-registrations-and-elevated-processes-with-uac-on-windows-vista.aspx) and
Per-User COM Registrations and Elevated Processes with UAC on Windows Vista SP1 (http://blogs.msdn.com/cjacks/archive/2008/06/06/per-user-com-registrations-and-elevated-processes-with-uac-on-windows-vista-sp1.aspx)...

... discuss some related issues in Vista. These also apply to Windows 7. You almost have to read between the lines to see XP in there anywhere.


If you are creating Windows Installer packages (.MSI) for deployment you can get more control over file security and component registration. With some work perhaps InnoSetup or other tools can offer similar flexibility.

But you want security on the libraries set properly, you want to avoid component library self-registration, and you need to perform the proper "type" of installation. Windows Installer can run in two basic modes: per-machine and per-user.

In an older downlevel OS (XP, Win2K) this is governed by the MSI package's ALLUSERS property's value (or an overriding command line parameter when running MSIEXE manually). In current versions of Windows there are additional properties as well as your process elevation status that interact with ALLUSERS in different ways for a wider variety of installation options.


I don't think most VB6 developers are aware they're still packaging for the Win9x/NT 4.0 world of a decade ago. Often they get things to work on a machine with one user who is an admin or Power User - but this only works through the graces of Windows XP appcompat.

Sadly there is almost no information written for the VB6 programmer to use in unraveling this. It is just part of the VB6 tax Microsoft imposed when they decided to deprecate classic VB.

silverblatt
Apr 23rd, 2010, 09:00 PM
Thanks, dilettante, for an interesting and very relevant discussion of the issues here. But do you have any practical suggestion for how I can actually resolve this? We have an MSDN subscription, so we can download and use whatever Microsoft has. I've seen lots of references to Visual Studio Installer 1.1, but Microsoft has pulled that from its own sites, and seems to have strong-armed everyone else into removing all third-party download links to it. Is there some tool I can use to deploy this VB6 application to my end users? Those end-users don't have admin privileges, and I seriously doubt if management will consent to giving them those privileges.

dilettante
Apr 24th, 2010, 09:00 AM
I'd begin by checking the security on the OCX giving you trouble, on the target system following installing your application. If it isn't allowing Everyone (or at least some group covering all of your users) to have read and execute access then you probably need to fix this.

I'm not sure why the file might end up with incorrect security settings. Maybe they're wrong on the development machine and your setup software is carrying them across. Maybe your setup is setting them incorrectly on purpose (some packaging option?). Or perhaps the file is inheriting its security based on the ACL (http://msdn.microsoft.com/en-us/library/aa374872(VS.85).aspx) set on the directory this file is being copied into.

Check the Security tab of the OCX file and its folder's Properties after installation. Then go back and check the OCX file's security on the source machine.


Ideally you are packaging libraries like this from a redist folder you maintain, not by taking them from the live \Windows\System32, \Program Files\Common Files, etc. locations of your development machine. With PDW, you can put redistributable versions of files in the Redist folder (\VB98\Wizards\PDWizard\Redist) as PDW always picks up files from Redist before looking elsewhere.

silverblatt
Apr 26th, 2010, 02:43 PM
Thanks, dilettante! It was in fact a permissions issue. Granting read and execute rights on the .OCX file to Everyone on each local machine solved the problem.