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?
Who is Participating?
zorvek (Kevin Jones)Connect With a Mentor ConsultantCommented:
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.

zorvek (Kevin Jones)ConsultantCommented:
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

BIAPROAuthor Commented:
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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

BIAPROAuthor Commented:
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.  ??
zorvek (Kevin Jones)ConsultantCommented:
>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

BIAPROAuthor Commented:
Ok it will restart, only it will give a other problem, it has now 2 sessions active, teh 'old'one and the 'new' one
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].

BIAPROAuthor Commented:
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
Where's the need to restart here?  Maybe I'm not getting this?
BIAPROAuthor Commented:
as described in some screens higher I need to restart my program if some needed options at  formload
 are different
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
BIAPROAuthor Commented:
I understand, but in this case I would need a  Call RestartApp......  source code , right?
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
>>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.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.