Posted on 2008-06-22
Medium Priority
Last Modified: 2011-10-03
In some VB6 programs the user can set some options.  Due to this the program has to end and restart.
For now I give a pop-up to tell program will end after confirming popup, the I end program and close all files
Now user has to restart teh program himself,  how to create a way after ending the program to restart by itself?
Question by:BIAPRO
  • 6
  • 4
  • 3
  • +1
LVL 81

Expert Comment

by:zorvek (Kevin Jones)
ID: 21840078
Terminating and restarting an application is a lazy way to reset your settings. I have resorted to this type of application behavior ONLY when applying an update to the application or a referenced component. Why do you need to restart the application?

Assuming you have good reason for doing so then you will need a second "helper" application that, when launched, waits for the first instance to quit, launches the main application, and then exits. You can wait using a simple timer (easy but not efficient), or you can use a mutex. Below is some code I used for a helper application. You will need to add similar code in the main application to create the mutex before invoking the helper application and exiting.

Private Const WAIT_ABANDONED& = &H80&
Private Const WAIT_TIMEOUT& = &H102&

Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" _
   (ByVal lpMutexAttributes As Long, _
   ByVal bInitialOwner As Long, _
   ByVal lpName As String) As Long

Private Declare Function WaitForSingleObject Lib "kernel32" ( _
   ByVal hHandle As Long, _
   ByVal dwMilliseconds As Long) As Long

Public Declare Function ReleaseMutex Lib "kernel32" ( _
   ByVal hMutex As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

Public Sub Main()

   Dim Mutex As Long
   Dim Result As Long
   Dim DisplayProblem As Boolean
   Mutex = CreateMutex(0&, 0&, "ApplicationName")
   Result = WaitForSingleObject(Mutex, 5000)
   If Result = 0 Or Result = WAIT_ABANDONED& Then
      OpenDocument App.Path & "\" & "ApplicationName.exe"
      ReleaseMutex Mutex
      DisplayProblem = True
   End If
   CloseHandle Mutex
   If DisplayProblem Then
      MsgBox "A problem has occurred restarting the application. The application file is locked or the application is still running. Try rebooting your computer and running the application again.", vbOKOnly
   End If

End Sub


Author Comment

ID: 21840090
the reason I have to is I'am using a third party module wich adds HelpBalloons on every wished vbcontrol/text/cmd ect, also this module adds XP/Office style look to the forms, however when Helpballoons are activated the Xp/Office styles gives crazy colors/looks etc. to the forms, so when I start the program I take a look if help is wished or not not like below at form-load

  HelpFlag$ = GetSetting(appname:="HelpUser", section:="Tooltips", Key:="YesorNo")
   If HelpFlag$ <> "YES" Then
     Dim Descriptions As SkinDescriptions   '   Help-Ballons util not active , use Office Style
     Set Descriptions = SkinFramework.EnumerateSkinDirectory(App.Path, True)
     SkinFramework.LoadSkin App.Path + "\Office2007.cjstyles", ""
     SkinFramework.ApplyWindow Me.hWnd
     SkinFramework.ApplyOptions = SkinFramework.ApplyOptions Or xtpSkinApplyMetrics
     TOOLTIPS  '   Help-Ballons util is active , no use Office Style and load HelpBallons Text for all controls
   End If

Author Comment

ID: 21840095
this is had to change to:  PRIVATE  Declare Function ReleaseMutex Lib "kernel32" ( _
   ByVal hMutex As Long) As Long
else run-time error on PUBLIC then,
OpenDocument App.Path & "\" & "ApplicationName.exe"  wil give a error on OpenDocument  no sub,
I guess I have to create here somthing to re-start appl.  ??
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

LVL 81

Expert Comment

by:zorvek (Kevin Jones)
ID: 21840107
>this is had to change to:  PRIVATE  Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Good catch - that was an error in my code.

Here is my OpenDocument routine:

Private Const SW_SHOWNORMAL = 1

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
      ByVal hWnd As Long, _
      ByVal lpOperation As String, _
      ByVal lpFile As String, _
      ByVal lpParameters As String, _
      ByVal lpDirectory As String, _
      ByVal nShowCmd As Long _
   ) As Long

Public Function OpenDocument( _
      ByVal PathName As String, _
      Optional ByVal Parameters As Variant, _
      Optional ByVal Minimized As Boolean _
   ) As Long

' Open the requested document.

   Dim WindowOption As Long

   If Minimized Then
      WindowOption = SW_SHOWMINNOACTIVE
      WindowOption = SW_SHOWNORMAL
   End If

   If IsMissing(Parameters) Then
      OpenDocument = ShellExecute(0&, vbNullString, PathName, vbNullString, vbNullString, WindowOption)
      OpenDocument = ShellExecute(0&, vbNullString, PathName, CStr(Parameters), vbNullString, WindowOption)
   End If
End Function


Author Comment

ID: 21840144
Ok it will restart, only it will give a other problem, it has now 2 sessions active, teh 'old'one and the 'new' one
LVL 10

Expert Comment

ID: 21840161
The way I do this is to have a launcher application in my main app's resources.  When I need to relaunch my main application, I have a routine WriteResourceToFile, do that with the launcher, and then shell it.

The launcher is passed some commandline args 1. what it needs to re-launch, fso.BuildPath(App.Path, App.EXEName), [optional] 2.  the launcher, in my case, can either wait for the main app to end - before restarting it - or, cause it to end all by itself; this arg tells it what to do.  3/4/.... it can also pass back commandline args to the re-launching app - I commonly use a -nosplash flag for example [uses may already be sick of seeing the main app's splash screen].


Author Comment

ID: 21840172
sounds nice , but how to use that in my situation, what i do normally (in this case disabled else no restart at all anyway,)
160      myCaption = "ORDERS"
170     If App.PrevInstance = True Then
180         Me.Hide ' ----------------------- make sure this window is hidden
190         DoEvents
        ' -----------find the previous instance window based on the myCaption value set above
200         prevHwnd = FindWindow(vbNullString, myCaption)
        ' ----------------if found then make it the foreground window in normal state
210         If prevHwnd <> 0 Then
220             ShowWindow prevHwnd, SW_SHOWNORMAL
230             SetForegroundWindow prevHwnd
240         End If
250         End ' ---------------stop this one because one active-----protect user for double clicking -------
260     End If
        'Me.Show ' no previous instance, show the window and set its caption
270     Me.Caption = myCaption
LVL 10

Expert Comment

ID: 21840193
Where's the need to restart here?  Maybe I'm not getting this?

Author Comment

ID: 21840215
as described in some screens higher I need to restart my program if some needed options at  formload
 are different
LVL 10

Expert Comment

ID: 21840337
So, in my case pseudo code would be...

If NeedRestart(CHK_ALL) Then

    Call RestartApp(WriteResourceToFile(LAUNCHER), WAIT_FOR, "-nosplash")

    ' End *this* instance.
    Call UnloadAll

End If

Author Comment

ID: 21840351
I understand, but in this case I would need a  Call RestartApp......  source code , right?
LVL 17

Expert Comment

ID: 21841098
Is it acceptable in your situation to launch a new instance *then* close the current? That way you won't need a secondary application.

Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Const MY_FORM_ID As String = "Closing... [fb45s]"
Private Sub Form_Load()
    'check for previous instance
    If (App.PrevInstance = True) Then
        If (FindWindow(vbNullString, MY_FORM_ID) <> 0) Then
            'prev instance is closing, that's ok
            Call MsgBox("Only one instance allowed.")
            Call Unload(Me)
            Exit Sub
        End If
    End If
    'change caption just to know that a different
    'version loaded
    Me.Caption = Timer
End Sub
Private Sub cmdExit_Click()
    'save program settings here
    'to avoid prev-instance issues, set our window's text to something
    'we can identify later
    Me.Visible = False
    Me.Caption = MY_FORM_ID
    'launch new instance
    Call Shell(get_exe, vbNormalFocus)
    'close this instance
    Call Unload(Me)
End Sub
Private Function get_exe() As String
    Dim s_path As String
    s_path = App.Path
    If (Right$(s_path, 1) <> "\") Then
        s_path = s_path & "\"
    End If
    get_exe = s_path & App.EXEName & ".exe"
End Function
LVL 10

Expert Comment

ID: 21841117
>>I understand, but in this case I would need a  Call RestartApp......  source code , right?

Yes, you'd need to write something like the little launcher app I use.  If I remember correctly [been a long time since I've looked at the code for this], it was initially just a few lines of code, as it just used to wait - originally with a FindWindow/sleep loop.  This then went to a WaitForSingleObject call on the parent process; which I think it still uses.
LVL 81

Accepted Solution

zorvek (Kevin Jones) earned 1500 total points
ID: 21841302
The problem you had with my code above is that you just didn't exit the first instance. When you want to restart the application you need to:

1) Create a mutex.
2) Launch the helper application.
3) Exit as in quit as in terminate as in kill yourself.

The helper application will wait for you to quit (by watching for the mutex to go away) and then start the application again.


Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

599 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question