DAO 3.6 on Windows Server 2008 - vb6

For historical reasons,we have some legacy vb6 server side code running on two identical Windows 2008 server boxes that uses dao 3.6 to get to the back end MS access databases. This has worked fine for years, and we are currently in the process of migrating all the code. However, one of the servers the code is running on is getting flakey, so we need to move the code to a new server as the migrated solution will not be ready for a while.
The server that works ok is running Windwos Server Web 2008 Sp1 64 bit. The new server is Windows Server Standard 2008 R2 Standard Sp1.
In running tests on this new server, we started getting random freezing in the application. There is a simple loop that runs a select query on every table in the database.After adding a bunch of logging, it was freezing on a call to the OpenRecordset method of the DAO.Database object. Sometimes it would freeze for a few seconds, other times up to 10 - 11 minutes and then carry on. The queries being run are of this format, and should all return 0 records :
SELECT * FROM BlahBlah WHERE WriteTime > #25 Oct 2012 10:09:43#
When run directly on the database (i.e. in Access), they return fine. It's not the same query that locks up each time either. I thought that it might be something specific to our software that I hadn't managed to track down until I found a very similar post here (unfortunately with no reply except mine!)
http://www.vbforums.com/showthread.php?653166-Using-Dao-3.6-on-Windows-server-2008&highlight=dao+3.6+server+2008
The only thing I have found so far is that the version of DAO360.dll on the server that it runs on is 3.60.9704, and the version on the server with problems is 3.60.9756 (i.e. a newer version of Dao). I did not install or register anything manually, but installed Access 97 and Access 2003 on the new server, the same as the old server. I should also point out that If i move the back end code as-is to the old server, then the tests work fine, so I'm pretty sure it is not the code.
Now I know that DAO is outdated and all that, but I'm stuck with this codebase until the migrated solution is available and thoroughly tested, so any thoughts of where to look would be very welcome indeed. In the meantime, I'm going to try and manually register the 3.60.9704 version on the new server and run more tests to see if that is the issue, but it would be kind of weird if it is...

Aha ! Although we are only using DAO, not full blown access, this seems to be the answer
http://social.technet.microsoft.com/Forums/en-US/officesetupdeployprevious/thread/2a34fc07-0a1e-4248-b866-2b1c60aabba2
When I looked a bit more into it, the server that the code is running on fine is Windows 2008 webserver, which, although it is 64 bit, is a completely different beast to the OS on the new machine which is Windows Server 2008 R2. Solution seems to be to go back to an older OS on the server, rather than re-writing the whole app, which is an easy thing to do for us.
Luckily, this only has to run for another few months or so, as the whole thing is being re-written.

Related

Configure Oracle 19c to manually start up

I installed Windows 10 on my Lenovo T540p laptop. Nothing special of course. I work as a developer, so I also installed Visual Studio 2019, SQL Server 2019 and Oracle 19 c.
Now, most of my work is done on SQL Server, but I do have 1 or 2 clients which use Oracle, requiring me to have a working Oracle instance on my machine.
But... I only need it like 10% of the time, so ideally I would like to configure the Oracle services so I can manually start them when I need it.
Been playing around with this in the past, but it appears simply putting the services on manual isn't enough.
Googling this question gave me a couple of ideas on how to manually start up a db, but besides 1 question here I didn't actually found anything (even partialy) usable. Anyone here who can tell me how to best pull this off?

VM & MS access - ExportWithFormatting PDF not working while in background

I have a problem that i have a difficult time explaining, which makes any online search very hard. Here is my dilema.
I'm migrating a VM. The purpose of this machine is to compile send out daily/weekly/monthly reports. I know there are other ways (like Power BI) but this is the situation we are in right now. The older machine has win10 pro and office 365 installed while the new has win10 enterprise version and office 2016 installed. This machine runs 24/7 in the background running specific tasks (via system scheduler app) at given times, that is it's a Virtual machine and has done so without issues since it was created. The reason for the migration is because we need to domain change and bring the machine under a new corporate policy and we don't want to do this on a live server.
We've set it the VM's the same way, same programs and same settings. Everything seams to be running smooth expect for this one thing, and here is the problem i have a hard time to explain or figure out:
MS Access will update the tables and the computer will run the tasks as set but it will not export the data to pdf unless i have a remote desktop connection open. Will not export the pdf's otherwise. MS Access uses a autoexec macro where the pdf export is set with ExportWithFormatting. This works without issues on the old server.
We thought this to be a permission or user specific issue at first but even re-creating the tasks did not work and changing paths. Otherwise also i expect we would have problems with tables updating, specially since it works when you have an active remote desktop conn running.
I'm lost and therefore hoping this community will be able to help or guide me to a solution.
I believe that we found the reason for this. It was caused by windows easy print and the printer drivers of the machine. It worked for some reason differently between the servers. after reinstalling the printer drivers and a few restarts it started working. It exports now from access again.
This is at least solved.

Script works on Windows Server 2003 but returns error 0x8007000e on Windows Server 2012

I've a Perl script that forks in order to use Win32::OLE to extract PNGs of slides from a Powerpoint presentation. I'm in the process of migrating it from my old server (Windows Server 2003) to a new server (Windows Server 2012). The script works fine on the old server (which has Microsoft Office 2010) but on the new server (with Microsoft Office 2016), the script bombs with an error about there not being enough storage available:
Win32::OLE(0.1712) error 0x8007000e: "Not enough storage is available to complete this operation"
I've found quite a few references to this error code, but none particularly useful. Whilst this Microsoft support article says what the problem is and what to do to fix it, I have no idea why this is suddenly an issue now I'm moving to a different server and it doesn't seem to apply to my situation.
The new server has loads of spare disk space and RAM, so there should be plenty to go around. (The old server has far less of both, but that still works.)
Could this be something to do with the new server being 64-bit?
Could it be because of the differing versions of Office?
Could Apache or Perl be configured differently by default than when installed on the old server? (It's a new installation of each, but from the same source as on the old server, and I can't find any configuration that limits memory.)
One interesting point that leads me to believe that it's something to do with the script running via Apache (v2.4.27) is that if I run it from the command line (requiring a minor modification), it works fine. Apache runs as a service and I've tried running it as the same user for which it works on the command line, and that has no impact.
I've run out of places to look and things to try now, so any help would be appreciated.
UPDATE (21 August): Since nobody seems to have any ideas, I refactored my code slightly so that it gets called via a scheduled task. That works fine, supporting my theory that it's something to do with it being run via Apache. I'll keep this question open, partly in case a solution is presented and partly in case my workaround can help anyone else who has a similar problem.

Problem in VB6 COM+ application reinstall

We are experiencing a difficult problem which has been puzzling us for some time. We have two MSI setup files containing COM+ components and GUI respectively. The applications in both are written in VB6.
After a lot of testing we have arrived at this:
Application initially installed: Works.
Application uninstalled, new version installed: Does not work.
New application uninstalled, old application installed again (should work): Does not work.
The components are installed on Windows Vista clients, initially by Active Directory deployment, but testing is done by removing that deployment from AD, manually uninstalling and manually installing.
With “Does not work” I mean: Unable to complete a transaction. It seems to be a timeout on anything between 200 and 445 seconds. The GUI application is using the COM+ components to DTC to a server witch a MSSQL database.
Now why am I posting such a specific error? I'm looking for information regarding:
Any Windows Update update of MSDTC / COM+ the past year that could affect new installations.
This may be a common problem that others have a hint to what could be causing it.
Is there a COM+ cleanup utility to remove "old junk"?
Could this be a result of how Windows Vista handles the old "dll-hell" problem, that the new version introduces a new shared file?
Could it be something with versioning on components? (We have hundreds of them, difficult to say)
Ok, weird.
It seems installing SQL Native Client and opening for DTS in the local firewall solved the problem. The problem was actually that the SQLOLEDB provider seemed to break when reinstalling the application. This was not the case 1 year ago with the same executable, so something could have been changed on the network or by windows update.

Does Vista do stricter checking of Interface Ids in DCOM calls? (the Stub received bad Data)?

I hope everyone will pardon the length, and narrative fashion, of this question. I decided to describe the situation in some detail in my blog. I later saw Joel's invitation to this site, and I thought I'd paste it here to see if anyone has any insight into the situation.
I wrote, and now support, an application that consists of a Visual Basic thick client speaking DCOM to middle tier COM+ components written in C++ using ATL. It runs in all eight of our offices. Each office hosts a back-end server that contains the COM+ application (consisting of 18 separate components) and the SQLServer. The SQLServer is typically on the same back-end server, but need not be.
We recently migrated the back-end server in our largest office -- New York -- from a MSC cluster to a new virtual machine hosted on VMWare's ESX technology. Since the location of the COM+ application had moved from the old server to a new one with a different name, I had to redirect all the clients so that they activated the COM+ application on the new server. The procedure was old hat as I had done essentially the same thing for several of my smaller offices that had gone through similar infrastructure upgrades.
All seemed routine and on Monday morning the entire office -- about 1,000 Windows XP workstations -- were running without incident on the new server. But then the call came from my mobile group -- there was an attorney working from home with a VPN connection that was getting a strange error after being redirected to the new server:
Error on FillTreeView2 - The stub received bad data.
Huh? I had never seen this error message before. Was it the new server? But all the workstations in the office were working fine. I told the mobile group to switch the attorney back to the old sever (which was still up), and the error disappeared. So what was the difference? Turns out this attorney was running Vista at home.
We don't run Vista in any of our offices, but we do have some attorneys that run Vista at home (certainly some in my New York office). I do as well and I've never seen this problem. To confirm that there was an issue, I fired up my Vista laptop, pointed it to the new server, and got the same error. I pointed it back to the old server, and it worked fine. Clearly there was some problem with Vista and the components on the new server -- a problem that did not seem to affect XP clients. What could it be?
Next stop -- the application error log on my laptop. This yielded more information on the error:
Source: Microsoft-Windows-RPC-Events
Date: 9/2/2008 11:56:07 AM
Event ID: 10
Level: Error
Computer: DevLaptop
Description: Application has failed to complete a COM call because an incorrect
interface ID was passed as a parameter.
The expected Interface ID was 00000555-0000-0010-8000-00aa006d2ea4,
The Interface ID returned was 00000556-0000-0010-8000-00aa006d2ea4.
User Action - Contact the application vendor for updated version of the application.
The interface ids provided the clue I needed to unravel the mystery. The "expected" interface id identifies MDAC's Recordset interface -- specifically version 2.1 of that interface. The "returned" interface corresponds to a later version of Recordset (version 2.5 which differs from version 2.1 by the inclusion of one additional entry at the end of the vtable -- method Save).
Indeed my component's interfaces expose many methods that pass Recordset as an output parameter. So were they suddenly returning a later version of Recordset -- with a different interface id? It certainly appeared to be the case. And then I thought, why should it matter. The vtable looks the same to clients of the older interface. Indeed, I suspect that if we were talking about in-process COM, and not DCOM, this apparently innocuous impedance mismatch would have been silently ignored and would have caused no issues.
Of course, when process and machine boundaries come into play, there is a proxy and a stub between the client and the server. In this case, I was using type library marshaling with the free threaded marshaller. So there were two mysteries to solve:
Why was I returning a different interface in the output parameters from methods on my new server?
Why did this affect only Vista clients?
As my server software was hosted on servers at each of my eight offices, I decided to try pointing my Vista client at all of them in sequence to see which had problems with Vista and which didn't. Illuminating test. Some of the older servers still worked with Vista but the newer ones did not. Although some of the older servers were still running Windows 2000 while the newer ones were at 2003, that did not seem to be the issue.
After comparing the dates of the component DLLs it appeared that whenever the client pointed to servers with component DLLs dated before 2003 Vista was fine. But those that had DLLs with dates after 2003 were problematic. Believe it or nor, there were no (or at least no significant) changes to the code on the server components in many years. Apparently the differing dates were simply due to recompiles of my components on my development machine(s). And it appeared that one of those recompiles happened in 2003.
The light bulb went on. When passing Recordsets back from server to client, my ATL C++ components refer to the interface as _Recordset. This symbol comes from the type library embedded within msado15.dll. This is the line I had in the C++ code:
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename ( "EOF", "adoEOF" )
Don't be deceived by the 15 in msdad15.dll. Apparently this DLL has not changed name in the long series of MDAC versions.
When I compiled the application back in the day, the version of MDAC was 2.1. So _Recordset compiled with the 2.1 interface id and that is the interface returned by the servers running those components.
All the client's use the COM+ application proxy that was generated (I believe) back in 1999. The type library that defines my interfaces includes the line:
importlib("msado21.tlb");
which explains why they expect version 2.1 of Recordset in my method's output parameters. Clearly the problem was with my 2003 recompile and the fact that at that time the _Recordset symbol no longer corresponded to version 2.1. Indeed _Recordset corresponded to the 2.5 version with its distinct interface id. The solution for me was to change all references from _Recordset to Recordset21 in my C++ code. I rebuilt the components and deployed them to the new server. Voila -- the clients seemed happy again.
In conclusion, there are two nagging questions that remain for me.
Why does the proxy/stub infrastructure seem to behave differently with Vista clients? It appears that Vista is making stricter checks of the interface ids coming back from method parameters than is XP.
How should I have coded this differently back in 1999 so that this would not have happened? Interfaces are supposed to be immutable and when I recompiled under a newer version of MDAC, I inadvertently changed my interface because the methods now returned a different Recordset interface as an output parameter. As far as I know, the type library back then did not have a version-specific symbol -- that is, later versions of the MDAC type libraries define Recordset21, but that symbol was not available back in the 2.1 type library.
When Microsoft got the security religion, DCOM (and the underlying RPC) got a lot of attention, and there definitely were changes made to close security holes that resulted in stricter marshaling. I'm suprised you see this in Vista but not in XP, but its possible that additional checks were added for Vista. Alternatively, its possible that optional strictness in XP was made mandatory in Vista.
While I don't know enough about MDAC to know if you could have prevented this, I do know that security is one of the few areas where Microsoft is pretty willing to sacrifice backward compatibility, so it is possible you could not have done anything "better" back in 1999.

Resources