Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Stop multiple runs?? 5

Status
Not open for further replies.

NeilFrank

Programmer
Mar 12, 2000
167
CA

How can I prevent my packaged and deployed App from running more than once on the host computer? This happens if the user carelessly clicks the desktop icon more than once.

This was of course not a problem when I was working with the .vbp version, since Run/Start (F5) was not available after the first click.
 
if app.previnstance then
Unload Me
end if

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Should have mentioned to place that in the Form_Load Event.

[gray]Experience is something you don't get until just after you need it.[/gray]
 
What if I've got a formless application? Or that I more properly start up via a Main procedure rather than a Form?
 
Thanks strongm, I'm honoured [blush]

[gray]Experience is something you don't get until just after you need it.[/gray]
 
'First item in module start up sub
Sub main()
If App.PrevInstance Then End
End Sub
 
I'd make that

'First item in module start up sub
Sub main()
If App.PrevInstance Then Exit Sub
End Sub

 
Thank you very much, gurus, for this simple yet elegant solution. Microsoft sometimes comes through when you need them.

I have an MDI app and have put the following code in the MDIForm_Load routine:

If App.PrevInstance = True Then
Unload Me
Close
End
End If

No doubt this is overkill, but it appears to work.
 
Neil, get rid of the Close and the End statements.

Furthermore, I'd like to observe that eschewing (as one would the plague) overall methodologies that include concepts of the type "overkill but it appears to work" would be a strong career move for you, unless you intend to create architetural humor along the lines of Rube Goldberg. :)
 
If one just exits from the sub main is there any possibility that the app has not completely stopped? (say if a splash form has been activated before the sub main and still is visible)

Is there a reason for not ENDing the program?
 

In fact, I am experiencing 'real life' difficulties in just how I code the App.PrevInstance check. Although a 2nd instance of My App does not seem to open when I re-click the desktop icon while the 1st is running, when I close the latter I am left with a "not responding" (per Windows Task Manager) instance my App, which I presume is the thwarted 2nd.

I am researching this . . . and studiously avoiding overkill.

More to follow.
 
>say if a splash form has been activated before the sub main

Given that in your own example, Ted, you specify that the App.Previous test is the first item in the startup sunb, how would a splash screen be activated?
 
True, regarding my first example but I have seen other's code where the splash is the first form as listed in project properties. The sub load of splash then runs Sub Main in a module where the app proper starts then unloads splash when all variables are loaded or after a time delay so people can see copyright notices.
I was drawing this possibility to the original questioner and recommending END to close the application. Also Unload frmSplash before END would ensure nothing was left behind as long as End was in the module and not on the form code(I hope)

Do you know of any problems with using END?
 
Yes, tedsmith, I unfortunately do know of a problem using END.

I discovered this in tracking down the problem I described earlier in this Thread (5 Jan 08 10:35). It turns out that it is not necessary to attempt to open a 2nd version of my packaged and deployed App in order to generate the "not responding" version.

Thus, if I simply open and then immediately exit from my App without invoking any of its functionality, I am still left with a non-responding 'ghost' version that is hogging a ton of CPU ( ~ 100 K).

In my App, my startup form is its MDIMain form and my End statement is in its Form_Unload procedure. I do open a Splash screen from MDIMain.Form_Load, but I make sure this is unloaded in MDIMain.Form_Unload. Although no other forms have been loaded, to be sure, I make sure all forms are unloaded here before End, via:

Public Sub MDIForm_Unload(Cancel As Integer)

Dim MyForm As Form
For Each MyForm In Forms
Unload MyForm
Next

End

End Sub

But I still get my ghost. And this only happens in my packaged and deployed version, not when i run the .vbp version.

Thoughts?
 
> For Each MyForm In Forms
> Unload MyForm
> Next

Have you tried;
Dim i as Integer
For i = Forms.Count - 1 To 0 Step -1
Unload Forms(i)
Next

You should not need End.
 
Ted, just do a search in this forum. You will find plenty of us advising against using End with reasons why included.
 
You solved my problem HughLerwill. Much obliged.

Indeed, it is _essential_ that I get rid of End in MDIForm_Unload. This clears up - somehow - the problem of the 'not-responding' version appearing when I close my packaged and deployed App.

Perhaps this could be added to the list strongm references.
 
Long ago I had a similar problem with unloading forms and I found the following Info:

Ensuring that all Forms Unload
When a Visual Basic program ends, all of its forms should be unloaded and removed from memory. Unfortunately Visual Basic does not take care of this automatically. Particularly if your program contains a lot of forms, it is possible for one or more forms to remain in memory even after the program terminates. Remember, calling a form's Hide method or setting its Visible property to False does not unload it. Even if you explicitly unload a form (using the Unload procedure) it can still take up resources unless the form's reference is set to Nothing. This tip shows you how to ensure that all of a program's forms are unloaded and their resources released upon program termination.

This technique makes use of the fact that a Visual Basic application has a global Forms collection whose elements represent all of the application's loaded forms. You could loop through this collection, unloading all forms as shown in this code snippet:

Dim f As Form
For Each f In Forms
Unload f
Set f = Nothing
Next f

There's a problem with this straightforward approach, however. If you execute this code from a procedure it works fine, but if you call it from the main form's Form_Unload event procedure it will try to unload the main form which is already in the process of unloading itself (otherwise the Form_Unload event procedure would not have fired). You can get around this potential problem as follows:

Public Sub UnloadAllForms(Optional FormToIgnore As String = "")

Dim f As Form
For Each f In Forms
If f.Name <> FormToIgnore Then
Unload f
Set f = Nothing
End If
Next f

End Sub

With this procedure in place you would call it like this from the main form's Form_Unload event procedure and it will unload all forms except the main form:

UnloadAllForms Me.Name

If calling it from a separate procedure, pass no argument and the procedure will unload all of the program's forms.

 
Very interesting three57m.

I understand the pitfall: the potential for an infinite loop.

FWIW, the code suggested by HughLerwill that I use:

Dim i As Integer
For i = Forms.Count - 1 To 0 Step -1
Unload Forms(i)
Next

_is_ in my main form (MDIForm_Unload), and appears to proceed smoothly.

But I think I'll heed your caution!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top