INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Problem with the DBGrid32.ocx from 2010

Problem with the DBGrid32.ocx from 2010

(OP)

I have been using and installing on customer machines the DBGrid32.ocx from 1999 v. 5.1.81.4

There was a security update in 2012 for several VB6 components, which could be downloaded and installed.

I found out that there seems to be a bug in this DBGrid32.ocx from 2010 v. 5.1.98.13, which causes an error 3265 when referencing the column by it's field name rather than an index:

DBGrid1.Columns.Item("SomeField").Value

I always reference the column by the field name, so that if the query/table field order changes, all the references do not need to be changed.

The program has worked fine fpr years on hundreds of customers machines, because I always install the older version.

One of our newer customers uses GeoMedia, and this application also uses the DBGrid32.ocx. But the developers of GeoMedia have obviously downloaded the security package and distribute the newer Ocx - then my program stops working properly.

When the customer manually removes the newer ocx (de-register) and replaces it with the older one, all programs work fine again.
And, the customer should be required to do this, and is complaing about it.

GeoMedia confirmed their program will work with the older ocx, but rightfully says that they are using the newest version of the ocx.
However, that would be the case, if there was a further update of the ocx coming, which isn't the case. MS will evidently not be fixing this.
(There were similar problems with other ocxs, like the mscomctl.ocx, which MS did give a correction for.)

So, does anyone have an idea how to best handle a situation like this?
Maybe the older ocx could just be installed isolated?

Thank you for any help!


So, does anyone maybe have an idea how

RE: Problem with the DBGrid32.ocx from 2010

This OCX was included in the ill fated "Security Rollup" issued by Microsoft a long time ago (as in Demceber 2008 or so). They have "ready fire aimed" themselves with this many times, trying to fix it and reissue it.

The last one I tested was from April 2012 I believe.

Many of these controls have strange "off by 1" errors in them. Some are very blatant: Winsock.RemoteHost returns values truncated by 1 character for example. Others are somewhat subtle and related to collection indexing. Your problem seems to be one of those.

There isn't any workaround: just never install these "Rollups." As far as I know none of them can be safely uninstalled once installed, certainly the earlier attempts craftily leave no uninstall info behind so you can't delete them through the normal Control Panel Programs & Features applet.


The way I survive this is to use clean dvelopment machines that do not have these "Rollups" installed. Then I use reg-free COM packaging to isolate these OCXs.

What this does is use manifests to provide an Activation Context for these OCXs. That allows my programs to have private copies of working versions of such OCXs that do not need to be registered on target machines.

Then it doesn't matter if a user installs one of the "Rollup" attempts or a 3rd party program that installs a flawed OCX. It also helps protect your applications from other applications packaged using the evil "InnoSetup" which often doesn't manage ActiveX registration properly and thus can break other applications through DLL Hell.

Just say "No! No!" to "Inno!"

To use reg-free COM additional tools are needed. Use MMM if you can find it anymore (the author's web hosting went away). Or consider the commercial Side-By-Side Manifest Maker.

RE: Problem with the DBGrid32.ocx from 2010

Oops!

"Demceber" above = "December" - sorry.

RE: Problem with the DBGrid32.ocx from 2010

BTW:

The one from April 2012 (VB60SP6-KB2641426-x86-ENU.msi) seems to still do everything my test program uses, plus:

CODE

MsgBox dbgrdData.Columns.Item("Last Name").Value 

... is working fine.

This one reports its version (.AboutBox method) as: 5.01.9813

I have not retested the other OCXs in the package though.

As far as I can tell this is the one available at Microsoft Visual Basic 6.0 Service Pack 6 Security Rollup Update.

And you still would need to use Reg-Free COM/SxS Assembly Isolation to deploy and use this version reliably.


But all of that said...

This seems to be the same version that is giving you fits.

RE: Problem with the DBGrid32.ocx from 2010

(OP)


Thank you for your response, dilettante!

I use Advanced Installer.
It has an option - which I have never used or tested - "Components Isolated with this component". (see attached)

I guess this is what you mean.

I do get the errors on the same version you mentioned.

I need to make a correction with what I reported.
There are three different errors, and they do not happen on all underlying tables, which a grid's datasource ist based on. And, a table in another database with the same structure works fine.

1. Error 3265: It wasn't DBGrid1.Columns.Item("SomeField").Value, but instead DBGrid1.Columns.Item("SomeField").Caption
Sorry about that.
This error only happens sometimes.

2. Another problem, is that DBGrid1.Columns.Item("SomeField").Value will return an error "Column not found"

3. Yet, another problem, is some lists will show empty field values in all the rows - if there are less than 10 rows!

4. Still yet another problem is some lists will return a truncated DataField value (only the first 3 letters)



With some databases, this may happen on the same tables, or may happen on different tables.

Now, my first thought - and probably yours also - will be that something is wrong with the table structure, or the data, or how the code is written.
This isn't the case.

As I stated, none of these problems have ever happend with the older Ocx version.


I only use the DataControl as a data source object for the grid (no properties or connections set on the control). But the recordsets are created separately using the same connection/database object, and then are asigned to the DataControl's Recordset property.
I use DAO 3.6 but the databases are in Jet 3.5 format. I also tried it in Jet 4 format.
I compacted the db using the Access compact method, and the JetComp.exe from MS.
I removed all fields but one, removed all indexes and contraints, etc.
Nothing helps.

I'll put together a project and load it up.

RE: Problem with the DBGrid32.ocx from 2010

(OP)
Here is the sample project. Please test it just to see if the problem also happens for you.

There are two buttons which will set the grid to different tables.

With tblTest2, there are 10 records. If one more record is removed, then the grid will 9 empty rows.
Clicking on the buttons below the grid crashes on the same error.

Of the 4 errors mentioned in the previous post, only number 2 and 3 are shown in the sample.

So, apparently there is something very strange happening here.

Using the older Ocx, everything here works as expected.

But, instead of trying to figure what and why, I will try to use the isolation function.

RE: Problem with the DBGrid32.ocx from 2010

(OP)

Oh, and if one record is removed from tblTest2, then not only it shows blank rows, but also it also crashes like tblTest1 when the buttons below the grid are clicked.

RE: Problem with the DBGrid32.ocx from 2010

Sorry, I didn't mean to suggest that version 5.01.9813/5.1.98.13 isn't buggy. I just didn't trip over a bug when I tried a simple test.

One issue you're going to have is that almost nobody uses DAO, and thus those hoary old DAO controls like DBGrid left over from early VB though deprecated in 1998 when VB6 came out. So you won't find many people to help with this. The only example I have on hand myself only uses the DBGrid because it can be used "unbound" unlike the modern DataGrid. Even then it isn't very useful, so as I said I have just the one demo and no real applications.

So to make a long story short I don't doubt you've hit an issue or two.


I tried to figure out your "Advanced Installer" though the documentation is quite the wumpus hunt. It is pretty reticent about the topic, probably expecting users to be blind appliance operators slapping at brightly colored buttons of their pachinko-like product. The way it covers other topics suggests this too.

What little it does say on the subject suggests that it might do what's needed here. However it also says something scary:

Quote:

When creating an install package you can specify if the installer should copy some files used by a certain application, in the application's folder rather than in a shared location.

If it really does do that it is dangerous to use with VB6 programs.

When VB6 uses an isolated assembly you never want them deployed to the application's folder. It is only safe to deploy them to a subfolder within the application's folder or some entirely different folder like one under Programs\Common Files.

Failing to do this can result in your program causing more DLL Hell when it is run, since it could end up registering such components where they were deployed as isolated. This is a bad thing and you risk breaking other applications on the machine. You have no control over it, this is something the VB6 runtime will "do for you" when it finds a compent library in the app folder - and it hazardous that it's a crime those "Advanced" guys don't spell it out in huge blinking red letters.

Hopefully this "Advanced" installer gives you the option of choosing a deployment target aside from the application's folder. However it is very scary to think it defaults there. That makes it almost as dangerous as "No-No-Setup" can be.

RE: Problem with the DBGrid32.ocx from 2010

(OP)

Advanced Installer isn't doing it's "own thing" here, but uses the MSI guidelines, and builds the MSI package based on that.
I have tried PDW, Wise Installer for Windows Installer, InnoSetup, VS Studio, among several others, (though it has been years since) and have found AI (professional or architech) to best suitable for MSI package creation. Along side the fact that AI has a less expensive maintenance plan for our small company.

Everything can be done with AI which is based on the MSI setup guideline requirements, and much more. If someone doesn't agree with those MSI guidelines, that is a different thing.
I have been using it for about 8 years and have had very little problem installing our huge program (and what problems there have been, they have responded with a soulution within two days, or an update within a relative short time).

Advanced Installer says that - about copying the isolated file to the application folder - because that is just what the IsolatedComponents action in MSI says:
On the MSDN site: MSDN: IsolateComponents Action

Quote:

The installer installs the files of Component_Shared into the same directory as Component_Application.

But, it simply doesn't just do that. AI doesn't get into the depth of what it does, because it uses the MSI guidelines when building the MSI, and any one who is interested can look at those specific guidelines on the MSDN site.

This is what I now found about the MSI IsolatedComponents action, and what I have see, AI does just that:
And, here is what MSI does Installation of Isolated Components
and why: IsolatedComponents
I haven't done any thing with IsolatedComponents yet, and was concerned if this at all is the right thing to do here, or if there was a different solution to the problem.

Anyways, I really appreciate all the time you have taken here for this.
And I am still looking for the dangers you have mentioned on the MSDN site and will heed your warnings.
I will also check into that Side-BY-Side Manifest Maker. Thanks for the tip.

RE: Problem with the DBGrid32.ocx from 2010

Ok, I was able to check the actual Installer documentation and it makes it very clear this won't help you at all.

Isolated Components

Quote:

Because the current implementation of COM keeps a single full path in the registry for each CLSID/Context pair, it forces all applications to use the same version of a shared DLL. To enable an application to keep a private copy of a COM server, the system loader in Windows 2000 checks for the presence of a .LOCAL file in the application's folder. If the system loader detects a .LOCAL file, it alters its search logic to prefer DLLs located in the same folder as the application.

There are other requirements for .LOCAL DLL/COM Redirection not spelled out there, and those prevent the mechansim from working unless a component library was written to observe them. The biggest issue is the logic used in self-registration entrypoints which must accomodate .LOCAL scenarios by not trying to register within the HKLM registry hive.

.LOCAL "isolation" is an obsolete approach that never applied to components shipped with VB6 or those created in VB6 (ActiveX Project types). It is actually dangerous to use with VB6 because everything involved there forces HKLM registration.

.LOCAL was replaced by Side-By-Side Isolation due to its limitations and only remains in Windows for legacy compatibility.

You will need another tool to create the required .manifest files or embedded manifest resources. A conventional packaging tool generally doesn't do this, though I'm sure there could be exceptions. However even then they probably only create manifests for newly created components and not things like the OCXs that ship with VB6.

RE: Problem with the DBGrid32.ocx from 2010

I'd be tempted to use SxS as recommended by dilettante. A manifest maker, I like MMM although it's no longer available for download, will likely give you a manifest file contents something like this;

CODE -->

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <!-- Make My Manifest 0.9.305 -->
  <assemblyIdentity name="My.Soft.Computer.Software.Project1" processorArchitecture="X86" type="win32" version="1.0.0.0" />
  
  <file name="DEP\DBGRID32.OCX">
    <typelib tlbid="{00028C01-0000-0000-0000-000000000046}" version="1.0" flags="control" helpdir="" />
    <comClass clsid="{00028C00-0000-0000-0000-000000000046}" tlbid="{00028C01-0000-0000-0000-000000000046}" progid="MSDBGrid.DBGrid" description="The main grid object" />
  </file>
</assembly> 


for a project1.exe/.vbf file pair including DBGRID32.OCX 5.1.81.4.

Copy the code above into a text file called YOUREXENAME.exe.manifest and put it next to your YOUREXENAME.exe
Place a copy of the DBGRID32.OCX 5.1.81.4 into a sub folder called DEP in the folder containing the exe and the manifest file.

The exe will now use the copy of DBGRID32.OCX 5.1.81.4 in the DEP folder rather than a registered one elsewhere, if one exists at all.
Seems to work here, Process Explorer seems to agree; but I have no DBGrid based code to test it with.

RE: Problem with the DBGrid32.ocx from 2010

>The newest version...

Thanks for that dilettante

RE: Problem with the DBGrid32.ocx from 2010

I just hope the improved 0.13 I'm helping to alpha test gets released someday. But when a guy has moved to Android development it is hard to get him excited about old VB6 code.

RE: Problem with the DBGrid32.ocx from 2010

(OP)
Hi HughLerwill,

It worked just fine.
Thank you!

RE: Problem with the DBGrid32.ocx from 2010

Good, and now you know where to get MMM you may have the whole app running from a memory stick by the end of the week!

RE: Problem with the DBGrid32.ocx from 2010

Correct me it sounds too simple but if, when you recomplile, you put your old OCX in the same folder path that will contain your .exe.
Then in components, change the source of that OCX (with Browse) to that folder, I would have though your re-complied app would use that version rather than the one in System32.
This happens if you don't have a copy in System32 at all but I'm not sure what happens if you have it in both.
You might even give it a different name? (DBGrid32OLD.ocx)and regsvr and change the source in the Components dialog before recompiling.

RE: Problem with the DBGrid32.ocx from 2010

>You might even give it a different name? (DBGrid32OLD.ocx)and regsvr
diletantte will already have an answer on file for you but here's my attempt at one
Consider that when you register an OCX you are not registering the file name (although of course that is saved and associated in the registry); you are primarily registering the names of the objects within it (ref. progid="MSDBGrid.DBGrid" in the manifest above); when your code uses the 'progid' the registry looks for it, finds it, loads the file associated with it and executes the call. The registry though can only store unique 'progid's so an OCX containing a given 'progid' ,or set of them, can only be effectively registered once with a single file association. Of course it can be physically registered more than once but only the last registration will prevail (if successful).

RE: Problem with the DBGrid32.ocx from 2010

(OP)
Strange.

I tested several times by de-registering the older ocx and replacing it with the newer one and registering that one (all using Admin rights).

1. On my W7 dev machine (the application isn't installed there through an Installer program) all works using the manifest, no matter where the application is located (with in C\Program Files (x86)\ or outside of a protected folder . After removing the manifest, then the errors happen.

2. On a VM XP, where the Program is installed with Windows Installer, it also works with no problem. Remove the manifest, then the errors happen.

3. On a work colleague's machine with W7, when the application is installed with Windows Installer and started directly from the \Program Files (x86) MyApplication\ folder (with and without Admin rights), the erros still happen. (also, no Application Compatibility Flags are set).

I remotely checked everything, and did all copying and registering again, but the same problem.

However, when he copies the Application exe, manifest, and DEP folder containig the older OCX into a different, from non-protected folder such as C:\MyApp\, it works.

Any ideas what could be causing this?

RE: Problem with the DBGrid32.ocx from 2010

Don't think I can suggest much but ...
>.. the errors ...
I guess you mean the errors consistent with use of the unwanted version of DBGrid32.OCX, but have you actually verified the version of DBGrid32.OCX being used in each case using Process Explorer when the app is running, or by using a call to DBGrid's AboutBox method in your code.

RE: Problem with the DBGrid32.ocx from 2010

No compile-time fiddling is going to do anything about this situation because class ID values did not change between the older and newer versions of the library.


Quote:

However, when he copies the Application exe, manifest, and DEP folder containig the older OCX into a different, from non-protected folder such as C:\MyApp\, it works.

Any ideas what could be causing this?

From the description "from non-protected folder such as C:\MyApp\, it works" you almost certainly have a filesystem virtualization issue caused by copying files around. Or else...

There is also the issue of "Activation Context" caching. Once you run a program things can "stick" and just altering an external manifest or slipping one in there Won't take effect. If your program was previously installed on that machine this might be the culprit. Rebooting should corect that.

See Windows Vista Sxs Activation Context Cache, noting that all supported versions of Windows are "Vista" (Longhorn) in very meaningful ways. That includes Win7, Win8, Win8.1.


What you need is a manifest that isolates this particular library (DBGrid32.ocx) into a subfolder ("DEP" or "BIN" etc.) under the application's folder. This manifest should be embedded in the EXE. Though a separate .manifest file can work it is a strongly nonpreferred alternative.

Your installer should deploy the library to this subfolder. If you insist on an external .manifest file it must be deployed alongside the EXE. And the installer must not register the library as part of installation.

But it sounds like you are doing this already.

RE: Problem with the DBGrid32.ocx from 2010

(OP)

The manifest wasn't embedded, but everything else was done correctly.

I wasn't going to deploy this with the installation, as the problem with the newer Grid is only happening with a few workstations.
I also had already understood and warned not to register the ocx in the \DEP folder, manually (or with the installer, if used).

I checked the Virtual store, but except for an old log file under the application folder, it was clean of any other files.
We rebooted the system, but it didn't help.
We also tried with the application started with admin rights.

I guess about the only thing left is to try embedding the manifest, but I don't see how that will make any difference.

Just to mention it again: All works when the \DEP folder, manifest and exe are copied straight from \program files (x86)\ to C:\MyApp\. So, it cannot have anything to do with mispelling or missing files.
There is a second exe with a different name there also, and a manifest was created for that one too. But this exe also has the same DGBrid errors.

Am now stuck.


RE: Problem with the DBGrid32.ocx from 2010

No, running the application elevated should not make any difference. I'm not sure embedding will help either. I'm at a loss to explain what you are seeing.

For globally registered libraries "servicing" is basically the process of installing updates, and most of the time to a VB6 programmer this means Microsoft library updates serviced through Windows Update, etc. When you have isolated a library such updating processes know nothing about it and so cannot replace it with a new version. This means that as the vendor you have to be responsible for all updating.

Once you figure out where things are going wrong there isn't much reason to avoid deploying this with your installer. Clearly the "new" version is too broken for your programs to use it anyway, making it unlikely that servicing the library will ever be an issue because when Microsoft breaks something this way they almost never fix it.

RE: Problem with the DBGrid32.ocx from 2010

Something which occasionally helps a manifest file to 'take' (overcome the cache presumably) is to make sure the exe files last modified date is later than the manifest files last modified date, i.e. the exe is newer.

RE: Problem with the DBGrid32.ocx from 2010

I'm not so sure about that, perhaps you have it backwards?

At the blog post I linked a few posts back it says:

Quote:

To make a compromise, Sxs chooses the path of the entry manifest of CreateActCtx and its last modified time as the key. This means, if one of its dependent assemblies has changed, it is necessary to "touch" (i.e. change the last modified time of) the entry manifest for Sxs to see the change.

The blog post is discussing explicit calls to the CreateActCtx function, which also applies to usage of the Microsoft.Windows.ActCtx scripting helper object. But I would expect the cache to work the very same way when a manifest is auto-loaded through program runs and DLL loads.

RE: Problem with the DBGrid32.ocx from 2010

(OP)

Yes, I read that and remember already trying it.

But, just to make sure, I will test it again tomorrow (both ways).

As it is, it is already way past business hours here.

RE: Problem with the DBGrid32.ocx from 2010

>I'm not so sure about that...
Hmmm that's interesting because I have a personal use app with the option of applying the manifest to itself at run time(to make use of Common Controls 6) ; i.e. you click an option in the app, the manifest file is generated on the fly, and then the app restarts itself to apply the manifest (all happening in a non protected folder of course). This does not always work reliably and the app or the computer may have to be restarted several times before the app appears in its themed Common Controls 6 loveliness, however if I recompile the app with the manifest already in place the manifest always seems to be 'eaten' immediately. It could be nothing to do with file dates of course if Windows is keeping an eye out for other stuff like changes to minor version number of the exe which is set to auto-increment in my app.

RE: Problem with the DBGrid32.ocx from 2010

(OP)
HughLerwill, you were right.

I compiled a new exe and it works now.

It wasn't the date of the manifest, because it's date was newer than the exe on the system.
I tested this newer exe eith the older manifest already on the system, and also with a newer manifest, and it still worked in both cases.

Maybe, (but I not going to take the additional time to test it), if the manifest date was older than the older exe's date, something would have gotten jarred, though I doubt it.

I'd give you another Star if possible.

Thank you!

Thank you too, dilettante. You have also been a great help and I learned new things!!! I downloaded the MMM - great tool woth a thousand stars!

@Everyone: Have a nice day!

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close