Visual Basic Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming Languages - MoreVisual Basic Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old January 13th, 2004, 11:21 PM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
Loading forms in Main() to catch errors?

Hi,

I'm finally down to looking at ways to check whether our VB apps have all they have to run instead of just letting them crash and burn when loading a form that contains an OCX that has been replaced by a non-compatible version by another app... but I'm stuck at how to do this.

Since Windows doesn't seem to provide a reliable way to check for dependencies, I was thinking of starting an EXE in Main(), load/unload each form in the EXE, and catch any error, but this type of code obviously doesn't work (VB won't even let me run/compile it, for that matter):

---------- CODE ----------------
Sub Main()
OnError Goto ErrHandler

Dim iCounter as Integer
iCounter = 0

OnError Resume Next
Do
Err.Clear
Load Form & iCounter
If Err.Number = XXX then 'Form doesn't exist
Exit Do
ElseIf Err.Number = 336 Or Err.Number = 429 Or Err.Number = 50003 then 'Error loading form due to missing/wrong OCX
MsgBox Err.Description,MB_CRITICAL,"Error loading Form" & iCounter
End
End if
Unload Form & iCounter
iCounter = iCounter + 1
Loop While True

ErrHandler:
MsgBox "ErrHandler"

End Sub
---------- CODE ----------------

... and parsing through the EXE looking for FormX (with X=0 to ...) doesn't seem too reliable :-)

=> How do you handle missing/wrong dependencies past the original install?

Fred.

Reply With Quote
  #2  
Old January 14th, 2004, 12:28 AM
Fisherman's Avatar
Fisherman Fisherman is offline
Inherits Programmer.Slacker
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: Between my Id and your Ego
Posts: 2,193 Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Week 1 Day 13 h 55 m 17 sec
Reputation Power: 142
Send a message via ICQ to Fisherman Send a message via AIM to Fisherman
hmm... interesting question. Obviously, you can't do this in the form load procedure of the form containing the ocx. I wonder if you can execute a VBScript to determine the latest version of the OCX from the registry while a splash screen is loading?

Reply With Quote
  #3  
Old January 14th, 2004, 12:42 AM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
>>Obviously, you can't do this in the form load procedure of the form containing the ocx

Right, just add a module, create a Main() subroutine, and set the project to start on this routine, where you can check that your app has all its dependencies OK.

>>I wonder if you can execute a VBScript to determine the latest version of the OCX from the registry while a splash screen is loading?

Tried that, but it's a can of worms. Apart from maybe shelling out $700 to buy Desaware's VersionStamper which I haven't tried, there's no good way of checking dependencies, especially that you can call from an app at load time. For those interested, you can try DependencyWalker and Squealer when trying to build an installer, but those are not callable from the EXE itself.

Do you just add an error handler in every Form_Load() to catch errors?

Fred.

Reply With Quote
  #4  
Old January 14th, 2004, 09:32 AM
Fisherman's Avatar
Fisherman Fisherman is offline
Inherits Programmer.Slacker
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: Between my Id and your Ego
Posts: 2,193 Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Week 1 Day 13 h 55 m 17 sec
Reputation Power: 142
Send a message via ICQ to Fisherman Send a message via AIM to Fisherman
I would assume so, although I don't know what you would do with the error once you have it. What happened when you tried to check dependencies at load time? I'm sure that anything unregistered would give you a headache. Were you getting components with the version numbers unchanged?

Reply With Quote
  #5  
Old January 14th, 2004, 02:09 PM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
>>although I don't know what you would do with the error once you have it

Here's the ideal algo:

1. Start the app with Main()
2. Use a generic ForEach loop to fetch all the forms that live in the EXE, load/unload each form, and add an error handler that catches OCX-related errors, such as 339, 429, 50003, eg.

Dim fForm as Form
ForEach fForm in FormsInEXE
Load fForm
Unload fForm
Next fForm

3. If any OCX-related error pops up, either repair the issue silently or by asking the user, or just display a messagebox explaining the issue and asking them to call us

But, since there's no API to recurse through an EXE to list all its dependencies (OCX, at least), or its forms, at this point, I guess what we'll do is...

1. In Main() load/unload each form manually instead of using a generic ForEach loop, remembering to update this loop every time we add/remove a form in the project

2. If an error occurs, reregister either all the OCX's located in the app directory or just the offending OCX (by parsing Err.Description to know which OCX caused the error)

3. If the OCX can't be found in the app directory, either silently or explicitely fetch it from our site

>> What happened when you tried to check dependencies at load time? I'm sure that anything unregistered would give you a headache. Were you getting components with the version numbers unchanged?

Until now, we never handled this issue, so in case an OCX was missing (no, we didn't use an installer either :-)) or had been replaced by another app, the app would just crash whenever a form was loaded that required this component.

Another headache is that our development hosts don't all have the same SP, so we would end up with EXE's that depended on different versions of MS ActiveX controls, causing quite a lot of hair pulling :-)

But since we're about to ship a new app, I wanted to get to the bottom of this, and provide both error control/repair, and a good installer (NSIS.)

BTW, I just got error 50003 when opening a VB project on a host where I just installed a brand new VB5SP3. The error was due to the usual 1.x TypeLib number in the VBP (or was it an FRM?). Does anyone know what a TypeLib is, and the relationship between a TypeLib version # and the OCX four-digit version number, if any?

Thank you :-)
Fred.

PS: BTW, a list of the different version numbers for Microsoft components is available here:
http://support.microsoft.com/defaul...nfo.asp&SD=msdn

Reply With Quote
  #6  
Old January 14th, 2004, 03:55 PM
Fisherman's Avatar
Fisherman Fisherman is offline
Inherits Programmer.Slacker
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: Between my Id and your Ego
Posts: 2,193 Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Week 1 Day 13 h 55 m 17 sec
Reputation Power: 142
Send a message via ICQ to Fisherman Send a message via AIM to Fisherman
sorry, I'm drawing a blank here. I wish I could help, but without knowing the dependencies, I can't think of anything

Reply With Quote
  #7  
Old January 14th, 2004, 04:00 PM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
No worries :-) I googled quite a bit, and there doesn't seem to be any API to extract either forms or dependencies from an EXE.

Now I understand why some people either went back to developing VB apps without any dependeny other than the runtime... or dumped VB entirely :-)

Thx anyway
Fred.

Reply With Quote
  #8  
Old January 16th, 2004, 01:06 PM
Fisherman's Avatar
Fisherman Fisherman is offline
Inherits Programmer.Slacker
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: Between my Id and your Ego
Posts: 2,193 Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Week 1 Day 13 h 55 m 17 sec
Reputation Power: 142
Send a message via ICQ to Fisherman Send a message via AIM to Fisherman
fred - thought of something. The file system object has a method called "getfileversion". It would require work, but could you include an INI with the version numbers of your OCX's and have it check against the version on the target PC. It has another method called "FileExists" that you might use, then nest the "GetFileVersion" to first determine if the OCX exists on the client PC, then determine if it's the right version or not. If it is not, then enter a routine that would download the new version to the client PC (maybe using FTP), and use the registry API calls to register the new version? It's just a thought.

Reply With Quote
  #9  
Old January 16th, 2004, 02:06 PM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
Thanks for the idea :-) I didn't know the file system obj, but I was thinking of doing something similar since I already have some API-based code to extract version infos and build INI files.

I was thinking of building a batch file that would
1. parse VBP, FRM, BAS, and DEP files for dependencies, and save those in an INI file
2. vb5.exe /make myproj.vbp
3. use eg. PEBundle or EXE Bundle to stick the INI inside the EXE
4. In Main(), loop through each entry in the INI file, and either just stop with an error message saying such and such component is N.A. or wrong version, and/or offer to download it from the Net

Considering that the great majority of VB apps require components, I'm surprised this hasn't been streamlined. I've learned more about COM and install issues in a week than I ever wished to know :-)

Thanks again for your great help
Fred.

Reply With Quote
  #10  
Old January 16th, 2004, 02:38 PM
Fisherman's Avatar
Fisherman Fisherman is offline
Inherits Programmer.Slacker
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: Between my Id and your Ego
Posts: 2,193 Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level)Fisherman User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Week 1 Day 13 h 55 m 17 sec
Reputation Power: 142
Send a message via ICQ to Fisherman Send a message via AIM to Fisherman
wow. That sounds really complicated. I think I'm going to try and implement the method I suggested in my programs from now on. I just realized that I could have a separate header for each control specified by the control name with a version and url entry. at run time, I can check the version, and if necessary , use the url to download the ocx from the proper site. Good luck with your implementation. If you don't mind, could you send me an example when you get it completed? I'd like a peek if I could

Reply With Quote
  #11  
Old January 17th, 2004, 08:03 AM
edburdo edburdo is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 50 edburdo User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 5
Just remember to set your form = nothing in the loop... otherwise you get extra code left in memory...

Reply With Quote
  #12  
Old January 17th, 2004, 02:20 PM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
Even when using Unload?

Reply With Quote
  #13  
Old January 20th, 2004, 05:01 AM
fredtheman fredtheman is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 61 fredtheman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 54 m 15 sec
Reputation Power: 5
For those interested, and since VB (5; I don't use VB6 yet) doesn't offer a function to list all the forms contained in an EXE to load them in a loop.... you can't help but doing a bit of hard-coding.

In that case, we might as well just load a single control instead of a whole form, since the issue we're trying to solve is checking in Main() whether any OCX can't be loaded (since we provide an installer, this means that the control has probably been replaced by an incompatible version).

Here's some code:

'===============
Sub Main()
On Error GoTo ErrHandler

Dim myCol As New Collection
Dim MyObject As Variant
Dim myObj As Object

myCol.Add "MSComctlLib.TabStrip"
myCol.Add "MSComCtl2.MonthView"

For Each MyObject In myCol
MsgBox MyObject
Set myObj = CreateObject(MyObject)
Set myObj = Nothing
Next

Form1.Show
Exit Sub

ErrHandler:
MsgBox Err.Description, vbOKOnly, "Error n°" & Err.Number

End Sub
'===============

Since you made sure to keep a copy of all the OCX's you need in the app's directory, just add code in ErrHandler to either reregister all the OCX's in the current directory, or parse Err.Description to find which control is causing the problem, and just reregister this particular OCX. If the OCX can't be found or is corrupt, just download it from your web site :-)

Fred.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - MoreVisual Basic Programming > Loading forms in Main() to catch errors?


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump