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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to avoid to run the program if one is already running!! 1

Status
Not open for further replies.

SurvivorTiger

Programmer
Jul 9, 2002
265
US
Hi everyone;
Ok, lets say my program is already running, now if you double click on the exe file again, it would run a second one which i don't want to happen, because then that screws up somethings!
So, does anyone know how i can avoid that, for example is there a way to detect the program if it's running or no?

Thanks in advance AIM: survivertiger & Ye This Is Me
 
think this is what your looking for.

Private Sub Form_Load()
If App.PrevInstance Then
Exit Sub
End If
End Sub
 
doh!! had a hard day....

i meant: -

Private Sub Form_Load()
If App.PrevInstance Then
unload me
End If
End Sub
 
WOW, didn't think it would be that easy...
I thought I would have to do some sort of API call or something, but hey, THANKS!!
AIM: survivertiger & Ye This Is Me
 
ADoozer do nor worry, you are not alone. I tried to stop my app today using the same way - Exit Sub ... after 6 years in programming ... [sadeyes]
 
SurvivorTiger,
In that Form_Load, nothing will have loaded yet; you'll want an End in place of the Unload Me. Only in the Form_Load would you use an End; Unload Me would work elsewhere.

Another word of caution concerning App.PrevInstance: if your software's going to be run in a Windows NT environment, that check for App.PrevInstance could prevent a user on the shared desktop from starting the application.

My current project is a massive headache that uses both App.PrevInstance and API calls to prevent multiple instances. Both of these options can return false negatives (the calls will say there's no instance running when an instance is). Wish I had the time to either rewrite the suite of apps or code out the Mutex solution, but time doesn't permit.

VB is NOT a friendly language for foolproof handling of multiple instances, despite what it seems.
 
SJStanley: >In that Form_Load, nothing will have loaded yet; you'll want an End in place of the Unload Me. Only in the Form_Load would you use an End; Unload Me would work elsewhere.

im relatively new to vb (about 2years) and i dont have a problem using the code i posted (although usually i dont stick it in the form_load event!) can you explain to me why it works (i made a simple test form) and on which occasions it wont?

(im curious because one of my apps does use it in the form_load event)
 
Instead of starting the EXE with a form, start is with Sub Main. In sub main you can check e.g. a registry setting to see if the app is loaded. If loaded, it is easy to end, else
load and show the form from here. In form load set a registry entry and on form unload clear the setting. The Big Viking
 
I am sure that app.previnstance works.
But what I am interested now is, have any one tried to check if there is any instance of another .exe running?

For example, if I am running first.exe, I dont want my second.exe to run. Is there is any way that I can check that in VB?
 
SurvivorTiger

I might have what you need here....

I have a Sub that I called ALREADYRUNNING (it's below). I use an MDIForm for my main form & it gives me no problems. I call it pretty early in my startup module to keep it fom doing too much before going to the previous instance.

The only thing necessary from you is, you need to know the caption of your Main Form.



Public Sub AlreadyRunning()

' This sub will determine if a Windows App. containing the string (strWindowTitle)
' in the windows title bar is already running on the machine. This is to prevent the app from
' being run more than once on the machine at any time. If the app is already running, this fuction
' will activate that instance of the app and shut down the second attempt of the app.


Dim strSaveTitle As String

If App.PrevInstance Then

strSaveTitle = "CAPTION OF YOUR MAIN FORM" ' save the name of the app to a string

' rename this instance of the app to avoid an ambiguous reference of the titles between the apps
App.Title = "Duplicate instance of..........." & strSaveTitle

' activate the first instance of the app
AppActivate strSaveTitle

' send keystrokes to the first instance to restore its window state
SendKeys "% R {ENTER}", True

' end the second instance.
End

End If

End Sub





Good Luck! I Hope it helps

John [spidey] [americanflag] [unclesam]
 
You guys should keep something in mind. The form that is being loaded IS NOT THE APP. It is just the user interface to the app.

What I am trying to say is this. Why must the app load directly into the form. Load it with sub main. From sub main you can do all the checking that you want to do. I am sure that app.previnstance will work here. Do the checking before the form is loaded.

To stress my point I am busy with a n-tier system. At present there are 3 Active-X EXEs, and about 8 or 9 ActiveX DLLs. I have only two forms. The forms are not the app, they are only the user interface. Always keep this in mind. VB makes it way to easy to think of the form as being the app. In most small cases it can be, but the moment you want to do a serious design, this should no longer be the case. Yours sincerely,
The Big Viking
 
the big viking: while i think i understand what you are trying to say....

>lets say my program is already running, now if you double click on the exe file again, it would run a second one which i don't want to happen

the app.previnstance would handle this (i guess thats why its included)... in a form or in a module!! (an example of this not working may be as SJStanley suggests but he/she hasnt come back to say why)

>But what I am interested now is, have any one tried to check if there is any instance of another .exe running?

the code at developer fusion does exactly that (although it is a little overkill) (see below)


'Module Code
Option Explicit
Public Const TH32CS_SNAPPROCESS As Long = 2&
Public Const MAX_PATH As Integer = 260
Public Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type
Public Declare Function CreateToolhelpSnapshot Lib "Kernel32" _
Alias "CreateToolhelp32Snapshot" _
(ByVal lFlags As Long, ByVal lProcessID As Long) As Long

Public Declare Function ProcessFirst Lib "Kernel32" _
Alias "Process32First" _
(ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long

Public Declare Function ProcessNext Lib "Kernel32" _
Alias "Process32Next" _
(ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long

Public Declare Sub CloseHandle Lib "Kernel32" _
(ByVal hPass As Long)

'Form Code
Private Sub Command1_Click()
Dim hSnapShot As Long
Dim uProcess As PROCESSENTRY32
Dim r As Long
hSnapShot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
If hSnapShot = 0 Then
Exit Sub
End If
uProcess.dwSize = Len(uProcess)
r = ProcessFirst(hSnapShot, uProcess)
Do While r
List1.AddItem uProcess.szExeFile
r = ProcessNext(hSnapShot, uProcess)
Loop
Call CloseHandle(hSnapShot)
End Sub


survivor tiger: to clarify.... What EXACTLY do you want to do (to avoid any confusion)
 
BigViking,

Maybe I wasn't clear enough in my previous post. When I wrote "I call it pretty early in my startup module to keep it fom doing too much before going to the previous instance." I implied for it to be called from Sub Main.

All my apps (built into EXEs) start with Sub Main and use AlreadyRunning to prevent the user from starting up a second instance of the app. What AlreadyRunning does is when the user has the app minimized and double clicks on the icon again, a search of the apps running in Windows is made looking for the name of the app.

The confusing part may have been strSaveTitle = "CAPTION OF YOUR MAIN FORM" ' save the name of the app to a string. I have the title bar of the first form (my main form) display the name of the app to make it easier on the user to maximize the app after the app is minimized.

I should have written "WINDOWS TITLE BAR CAPTION HERE" to avoid the confusion. AlreadyRunning does not rely on forms or subs but on the name that is being used within Windows.

VB gives you the option of starting an app up with Sub Main or a form or anything else. It's good for it to be flexible like that to that the people working with it can program to their own personal preference.

I hope I cleared this up.

John [spidey] [americanflag] [unclesam]
 
ADoozer,
reguarding the post to you.....
>In that Form_Load, nothing will have loaded yet; you'll >want an End in place of the Unload Me. Only in the >Form_Load would you use an End; Unload Me would work >elsewhere.

this is not true. your code was fine. the Form_Load event fires right after the form has loaded (not before). Some people get confused since Form_Load will execute all of it's code before it acutally shows the form. However you can force the form to display by invoking the .Show method at the beginning of the Form_Load (before the rest of your Form_Load code) this will cause the form to display and then run the rest of the Form_Load code.
End should really be avoided at all costs. End will stop the program, but the Form_QueryUnload and Form_Unload will not fire. This is not a good thing since your Form_Unload should be where you are setting your form object = to nothing.
 
directdrive: thank u for the clarification, that is what i thought, however as i say i am relatively new to vb (compared with some of the tek tippers) and didnt know for certain!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top