-
May 31st, 2005, 12:34 AM
#1
Classic VB - How can I allow only one instance of my application to run at a time?
Method 1: You can read the PrevInstance property of the App object, if the value of this is True then another instance of the application is already running.
If your program starts with Sub Main, you can use this code to exit the program if another copy is already running:
VB Code:
'in sub main...
If App.PrevInstance = True Then
MsgBox "Already running...."
Exit Sub
End If
For forms you need an extra piece of code to also close the form, the following code should be placed in Form_load:
VB Code:
'in form_load...
If App.PrevInstance = True Then
MsgBox "Already running...."
Unload Me
Exit Sub
End If
Method 2: You can use the FindWindow API to search for open windows with your form caption.
Note that for this to work you must know the exact title to find, so if you change your window title within your program
(such as adding a file name, like Notepad does) then this will fail. Also, if other running programs have the same caption,
your program may not run at all.
VB Code:
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As
String) As Long
Public Sub Main()
Dim m_hWnd As Long
'Change Form1 to your form Caption.
m_hWnd = FindWindow(vbNullString, "Form1")
If m_hWnd > 0 Then
MsgBox "Program " & App.Title & " is already running..."
Exit Sub
End If
'Change Form1 to your form name.
Form1.Show
End Sub
Last edited by si_the_geek; Aug 21st, 2005 at 09:35 AM.
Reason: added explanation & tidied up
-
Dec 18th, 2007, 06:25 AM
#2
New Member
Re: Classic VB - How can I allow only one instance of my application to run at a time?
vb Code:
'Module
Public Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As SECURITY_ATTRIBUTES, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function FlashWindowEx Lib "user32.dll" (ByRef pfwi As FLASHWINFO) As Long
Private Const FLASHW_STOP = 0
Private Const FLASHW_CAPTION = &H1
Private Const FLASHW_TRAY = &H2
Private Const FLASHW_ALL = (FLASHW_CAPTION Or FLASHW_TRAY)
Private Const FLASHW_TIMER = &H4
Private Const ERROR_ALREADY_EXISTS = 183&
Private Const SW_RESTORE = 9
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Type FLASHWINFO
cbSize As Long
hwnd As Long
dwFlags As Long
uCount As Long
dwTimeout As Long
End Type
Public Mutex As Long
Private Sub Main()
Dim sa As SECURITY_ATTRIBUTES
Dim hwnd As Long
Dim FlashInfo As FLASHWINFO
sa.bInheritHandle = 1
sa.lpSecurityDescriptor = 0
sa.nLength = Len(sa)
Mutex = CreateMutex(sa, 1, App.Title)
If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
hwnd = GetSetting("AppName", "Section", "Key", 0)
ShowWindow hwnd, SW_RESTORE
SetForegroundWindow hwnd
FlashInfo.cbSize = Len(FlashInfo)
FlashInfo.dwFlags = FLASHW_ALL Or FLASHW_TIMER
FlashInfo.dwTimeout = 0
FlashInfo.hwnd = hwnd
FlashInfo.uCount = 3
FlashWindowEx FlashInfo
Else
FrmMain.Show
End If
End Sub
vb Code:
'Form
Private Sub Form_Load()
SaveSetting "AppName", "Section", "Key", Me.hwnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
ReleaseMutex Mutex
CloseHandle Mutex
DeleteSetting "AppName", "Section", "Key"
End Sub
-
Apr 16th, 2013, 04:41 PM
#3
Re: Classic VB - How can I allow only one instance of my application to run at a time
Here's another method that uses a locked file instead.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
May 21st, 2019, 02:42 PM
#4
Fanatic Member
Re: Classic VB - How can I allow only one instance of my application to run at a time
Is there a reason to use a mutex or a locked file when the simple App.PrevInstance can handle this? I'm deciding on which approach to use in my app and can't really see any reason to overcomplicate this. Am I missing something?
-
May 21st, 2019, 03:18 PM
#5
Re: Classic VB - How can I allow only one instance of my application to run at a time
You may want to ask that question as a thread in the Classic VB forum rather than posting a reply in this thread. While this thread is certainly relevant, it has only had a few posts to it in 14 years, so your question will likely be overlooked here.
My usual boring signature: Nothing
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|