Updating OLE Reference in VB6 app - vb6

I have an old vb6 app that I'm in charge of maintaining that saves, opens, and prints Word documents to a users computer. The other day when we switched from office 2003 to office 2010, I started to get complaints that the software would no longer open saved reports and print them. Removing Officer 2010 and installing 2003 fixes the problem.
The sub procedure that handles this is all vanilla msdn code and I'm unable to find anything that would tie it to a certain version of Word. My next thought is perhaps its the OLE dll reference. Where/how can I update the VB6 reference to the dll to work with the new version of office?
Any other suggestions would be greatly appreciated.

I'm not sure but as a guess it sounds like you are trying to use early binding. If so this is likely your problem.
There are numerous MS KB articles warning about this over a period of over a decade. Examples:
http://support.microsoft.com/kb/247579
http://support.microsoft.com/kb/245115
In other words: remove all references to any version of Word, declare all of the objects As Object, and use CreateObject() or GetObject() where appropriate instead of Set Obj = New LibName.ClassName.
These KB articles are old now, and the old rules that let you get away with compiling with a reference to Word 95 and still automate Word 2002 don't seem to apply anymore. Besides needing the oldest supported version of Office installed on your dev machine, I suspect upward compatibility was broken beginning in Office 2003.
Your best bet is late binding. The performance penalty is minimal for most programs so the biggest headache is losing IntelliSense.

If you just blindly update the reference, you'll likely break support for Office 2003. if that's not a problem, go for it.
if it is, you'll need to narrow down where in particular, the app is failing. There are some minor differences between revs of the automation model between versions. Not a lot, but they are there.
Most likely, the code is doing something in a way that makes it specific to 2003. MS does a pretty good job of maintaining backwards compat, but they aren't 100%

To answer your question "Where/how can I update the VB6 reference to the dll to work with the new version of office?": You need of course a computer with Office 2010 and VB 6 installed. If you open the project in the VB IDE, you can change the reference to the appropriate Word Library. The references are also noted in the VBP file, e.g. like this
Type=Exe
Reference=*\G{00020905-0000-0000-C000-000000000046}#8.0#409#C:\Program Files\Microsoft Office\OFFICE11\MSWORD.OLB#Microsoft Word 8.0 Object Library
Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#C:\Program Files\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library
Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#C:\WINDOWS\system32\SCRRUN.DLL#Microsoft Scripting Runtime
Then recompile.
Well, and if you are there, you can just start to debug and see, what happens in detail and why the reports fail. There's no way to change the reference without recompiling, if this was your question.
If it's plain vanilla code related to open, save and print, it's hard to imagine something going wrong.
On the other hand - are there any "base files" in Word format, which are used? May be they have an old format (from Office 95, have just seen this lately). Try to open those files manually and see what happens.

Related

Will having two versions of mscomctl.ocx referenced in an application cause problems?

I maintain a lot of old VB6 code. The programs have been around a long time and run on many systems with no problems.
Recently we have been having strange, random problems with these programs on Server 2012.
I noticed that the project file referenced mscomctl.ocx#2.0 and a form file in the project referenced mscomctl.ocx#2.1.
Project file (vbp)
Object={831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0; MSCOMCTL.OCX
Form file (frm)
Object={831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.1#0; MSCOMCTL.OCX
A process dump showed comctl32.dll was loaded twice
LoadedModule[39]=C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200.17359_none_bf105a8645f47e85\COMCTL32.dll
...
LoadedModule[42]=C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200.17359_none_8935f06086091acc\comctl32.DLL
From what I could Google, it seems that comctl32.dll is a dependency of MSCOMCTL.OCX, which is also loaded.
LoadedModule[47]=C:\Windows\SYSTEM32\mscomctl.ocx
Is this cause for alarm?
Thanks for any help.
Your project (.VBP file) probably lacks the proper setting for Upgrade ActiveX Controls.
Open that file in a text editor and remove any line:
NoControlUpgrade=1
Or open the project in VB6 and check the box in the Project Properties dialog.
The answer is YES!
After I went through hundreds of programs and set them all to version 2.0 for MSCOMCTL.OCX and recompiled them, the problem stopped (Server 2012 caches applications so it took a while but it stopped).
FYI: Setting the NoConrolUpgrade=1 appears to be useless. The Kill bits for the OCX force VB6 to override the setting.
First, yes, you probably answered your own question.
MS has never been good with 'side by side' installs, and even the "Side by Side" implementation they came up with was bone dead. So my guess is that you are correct in assuming that two versions will cause problems. But that is just a guess based on experience.
Moreover, and not so much an answer to your question, but I'm with you on the maintaining older vb - regardless of some moronic comments that vb5/6 won't work on 'new windows', it still does (as long as you don't use a microsoft installer).
Like you, I now have to face reality and deal with a new learning curve. (upgrading loads of 'old' stuff). At least you have server 2012 running. I'm just coming to terms with that mess.
In delving into new code, and trying as best I can to put away notions of the stupidity of the syntax, I find I'm discovering new things that I like. And some that simply confound logical reasoning.
Since stack is not a forum for discussion, as was pointed out last time I got blocked, if you want to compare notes on getting up to speed, you can reach me at gjr!rockley.net
I'm sure you can fig that out.
Either Way, Good luck with it.
Gary

Set VB6 reference to Microsoft Word 97 (Word 2007 installed)

I need to use the reference to Microsoft Word 97 in my VB6 development project. (Its a long story - in a nutshell if I use ref to MSWord97 then I can support Word 97+).
I use Microsoft Word 2007 on my development machine. Ideally if I could get away with NOT installing Word97, that would be great.
In VB6 I tried to set a reference to C:\Software\Microsoft\Office97Pro\OFFICE\mso97.dll (path to software - not installed) but that didn't work. I then tried regsvr32 mso97.dll but that gave me the error: mso97.dll was loaded, but the DllRegisterServer entry point was not found.
Anyone know what I need to do to get this to work? Or will I need to install Word 97 on my machine for it to work?
It sounds like you basically want to do as suggested in Writing Automation clients for multiple Office versions but ignoring the advice about using late binding.
The type library involved is MSWORD8.OLB, but I can't recall whether there is any legitimate way to obtain it without Word 97 or an Office 97 Edition including Word. Offhand I'm not sure what the impact of registering this tylepib would have on your Word 2007 installation either, since they may well share many ClassID values.
In the VC++ article PRB: Automation of Office Using #import Can Fail if Multiple Versions of Office Are Installed Microsoft seems to suggest this can be a viable strategy as long as you reference the proper OLB. This is probably less of a problem for VB6 than in C++ because VB6 doesn't use the VC++ #import semantics for locating typelibs. Then again they may be referring to run-time behavior, since the explanation concludes by once more suggesting late binding.
The article WD: How to Obtain the Word for Windows Type Library offers links to the Word 6 and Word 7 typelibs (links may no longer be good) but none for Word 97, which they suggest you obtain by installing Word 97.
In any case it only sounds safe to use the constants, enums, etc. from Word 97 and use late binding for all of your objects. This "half a loaf" is better than nothing. You could still do your initial development with early-bound declarations to geet "Intellisense" assistance, then go back and change all of the early-bound object declarations to late-bound As Object and replacing Set X = New TYPE by the corresponding late-bound CreateObject() call, leaving the actual strong typing as a trailing comment. One could also use conditional compilation #If/#Else blocks to make flipping back to early binding easier later.
Since obtaining MSWORD8.OLB legitimately may be impossible today, you might also consider OFF: "Built-in Constants in Visual Basic for Applications" (WC0993) which offers a download containing VB .BAS modules defining the constants for many old versions of Word and other Office applications. The download link works - as of right now at least!
Since named constants are the primary reason for the typelibs (considering that only late binding is truly safe) this might not be a bad compromise. You can take the .BAS file you need, clean it up (bound to be some warts in there), and even convert it to a custom "Generic Word" TLB containing just those constants and enums with a little effort. For that matter somebody may already have done this work. I'd suggest you try a few searches before writing your own "VB .BAS to ODL/IDL" compiler though.
When adding a reference to your project, look for MS Word x.0 Object Library where x is the version of MS Word you want to work against. I believe you can reference a lower version than Word 2007 (version 12.0). Look for 8.0.

Best way to update an old VB6 app

A small ma and pa shop came to me recently with a request to update a vb6 program one of their former part time employees made for them while home from college. On the cd the student provided is both the source code and a installer for the program, which extremely helps. I would like to just give them a new cd with a new installer and the updated source code. My question is, how do I go about creating or if easier updating a installer for a language that entered "Non Supported Stage" back in 2008?
Update:
Just to answer some of the questions, the updates they are asking for are just changing the wording of some labels and changing one control from a textbox to a combobox. They are a ma and pa shop and don't want to pay the cost to have the app re-written to a newer language, even though it has been recommended.
You're going to need a copy of Visual Basic 6 (or Visual Studio 6) which is difficult. If you have an MSDN subscription, I'm quite sure you can download it from their archive, but if not, you might need to buy a copy. Check EBay. Have the ma and pa shop purchase it at their own expense, and they should own it in case they want to make future changes. You can use it on their behalf to do work for them, if you're the only one using it, and just uninstall it when you're done.
Also, if you have a copy of Visual Studio 2005, technically you can "downgrade" to VS6 but you have to call Microsoft and have them send you the install program, and you're not allowed to use VS2005 concurrently with VS6. Yeah, I know...
Ok, so if you've got that far, get the source on your computer and get it under source control. I suggest Mercurial (specifically the TortoiseHg client). I've had lots of luck with it on a VB6 project, and it's free. (Don't use SourceSafe, even if it comes free with VS6!) The distributed nature of the Mercurial repository means you can hand them back a CD with the entire repository on it, and the next poor sap who has to make changes will at least be able to do a diff and know what you did.
As someone else here said, VB6 has a built-in utility for making install programs, but I think you had to have the Enterprise version for that. It's worth finding that out before you get a copy.
Now go ahead and make changes, but be very careful. Remember that you probably don't have any unit tests, so you're likely to break stuff. If you want to be professional about it, there are unit testing frameworks out there for VB6. For instance, vbUnit. Again, I suggest having the customer buy a copy (about $99 for a single developer seat, I think). If the change was anything more than changing the company logo on the splash screen, then this is something I'd invest in. Write tests that cover every module or feature you're going to change. If all the logic is in event handlers in the form itself, carefully remove the code you need to change out into modules that you can write unit tests for. Write the tests to verify the current functionality first.
Then go ahead and make your changes. If you've gone to the trouble of setting up a testing framework, then you might as well use some TDD and write your tests first. Write a test, make sure it fails, write enough code to make it pass, and repeat.
All of this still requires you to have a solid manual test plan to check the functionality at the end. That means you need a solid grasp of what it does. You can pretty much assume that no matter how careful you are, you'll break something you didn't understand. Make sure to give yourself enough time to fix other problems that pop up after you deliver it.
I recommend against re-writing it in .NET unless it's a really simple program with only one form. The effort likely isn't worth it.
Caveat: beware of 3rd party components the original programmer might have used, but not included on the CD. If they used some ActiveX or COM stuff that they purchased from a 3rd party, but they didn't license it to your customer, you might have to end up purchasing it again just to get it to compile.
EDIT:
Based on your extra information, if you're really just changing a couple of controls and wording, then I think you can get away without a unit testing framework. I would definitely use some source control though.
I do remember using the Package and Deployment Wizard, and I agree it sucked. I actually used a 3rd party installer, now that I think about it. However, if the changes are small and the original application used the PDW, I'd probably stick with that.
You Can Convert VB6 projects to .NET.
If you have Visual Studio 2005 or higher...
Or the worse case is re write the code using VB.NET.
Go to this Link.
Convert VB6 - .NET
If I recall correctly, Visual Studio 6 came with a rudimentary wizard for creating an installation program for a VB6 application. So, assuming that you have Visual Studio 6 installed for VB6, there should be an installer wizard that you can use. However, it may have problems deploying the VB6 runtimes on Vista or Win 7 machines. Perhaps another SO guru will have the answer to that one.
You can also use the freeware Inno Setup to create an installer for a VB6 application. More information can be found here. However, it requires more manual effort than what came with Visual Studio.

Can Delphi 5 generate a .PDB file that VS can use?

We've got this large application written in Delphi 5, and development is ongoing to this day. There is research going on into migrating to newer versions, but so far there is no success, as some 3rd party components have not been updated in ages and do not work on later versions.
In the meantime however people need to continue work on it. Now Delphi 5 IDE is no real treat. It's pretty bug-ridden and lacks a lot of features of contemporary IDEs which makes it difficult to use. Especially when it comes to debugging.
So I was wondering - would it be possible to use Visual Studio in the process? As far as I know the .PDB file format is pretty old and is well documented. Could it be possible to make the Delphi compiler to somehow generate a .PDB files for it's compiled results? Then the program could be debugged with Visual Studio, possibly to a much greater extent than in the original IDE.
Well, the absolute Holy Grail would be to move all development to VS, just keeping the compiler from Delphi, but I imagine that would be pretty impossible.
No, and neither can any other version of Delphi. You can use Map2Dgb to turn a detailed map file into a dbg file, though, and you can use that in WinDbg.
I'm curious what debugging features you're expecting to use in Visual Studio that aren't in Delphi 5 and that also don't rely on the IDE understanding the Delphi language. I was always rather pleased with Delphi 5.
BTW, you can vote for this feature here.
Note, that VS-compatitible debug info will be useful not only for debugging application (I agree: it's better to use Delphi), but it will be useful for using tools like Process Explorer. For example, Process Explorer may be able to show human-readable call stack, instead of RAW numbers.
I've tried tds2pdb and it works great for me.
Apparently you can't. Seems that PDB is after all a propieritary Microsoft format without documentation, and as such there are no other tools generating it. Pity. :(
I would recommend moving to a later version of Delphi. We have done this with various applications for clients. Moving to a newer version of Delphi is normally straightforward, but there were issues moving from D5 to D6 due to changes in the way components were handled (design time code being separated from run time) and the change to Unicode in D2009 was a bigger change.
The main thing is to sort out the third party components. We only ever use third party components that come with source so if the worst happens and the vendor disappears, we can still work on the components ourselves.
Which components are causing the issues?

What's the diff between VSS 6.0 and VSS 2005?

We've been using VSS 6.0 since time began, but yesterday I nabbed VSS2005 off of our MSDN subscription, it wouldn't let me install it off the ISO through Daemon Tools (not sure why, but I submitted error report to MS...). I noticed it had a program files directory right on the ISO, so I just copied the folder onto my hard drive. Well, I opened up the client and behold, a glamorous version of VSS 6.0 connected to the exact same DB.
Anyone know if I'm going to destroy everything by using it?
We moved from VSS6 to VSS2005 just over a year ago. The database structure is identical. The only caveat we found was if some people still used VSS6 on a database where others were using VSS2005. VSS2005 treats Unicode text files as text files, whereas VSS6 does not. Which means that when VSS2005 adds a Unicode text file, VSS6 sees it as binary (this affects csproj files among others).
Other than that, VSS2005 supports proper HTTP access to the database (provided server extensions are installed), improved LAN performance (again, with server extensions), and better file system dialogs (the nasty old ones are gone). However, the new file add dialog shows ALL files, not just the ones that aren't included.
Also, VSS2005 allows the provision of custom editors and differencing tools by file extension, which is very useful. For example, some of our XML files are encrypted, so we run a decryption tool before the difference tool by using this system, which has increased the efficiency of our review processes substantially.
There are also other tweaks here and there, mostly good but occasionally annoying.
Finally, nothing has been destroyed. In fact, there appears to have been less additional corruption in the database since the transition - but I wouldn't put this down to the new VSS as it wasn't a comprehensive test.
I'm pretty sure, that there is no more danger of destroying anything than when using VSS 6.0.
It's quite a long time ago since I last used VSS, but we also updated from version 6 to version 2005. As far as I remember, there were only some cosmetic changes in the client (VSS explorer), but the format of the database and also the available feature were exactly the same than in VSS 6.
You should be fine.
Since VSS just uses a file share for everything, and there's nothing that is really server based, you're fine. Not much has changed in the format of the database, mostly client side stuff.

Resources