Solved

ENDING A VB6 PROGRAM AND RESTART AUTOMATICLY

Posted on 2008-06-22
14
2,626 Views
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?
0
Comment
Question by:BIAPRO
  • 6
  • 4
  • 3
  • +1
14 Comments
 
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
   Else
      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

Kevin
0
 

Author Comment

by:BIAPRO
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
         Else
     TOOLTIPS  '   Help-Ballons util is active , no use Office Style and load HelpBallons Text for all controls
   End If
0
 

Author Comment

by:BIAPRO
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.  ??
0
 
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 Const SW_SHOWMINNOACTIVE = 7

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
   Else
      WindowOption = SW_SHOWNORMAL
   End If

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

Kevin
0
 

Author Comment

by:BIAPRO
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
0
 
LVL 10

Expert Comment

by:peetm
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].


0
 

Author Comment

by:BIAPRO
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
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 10

Expert Comment

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

Author Comment

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

Expert Comment

by:peetm
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
0
 

Author Comment

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

Expert Comment

by:zzzzzooc
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.



Form1:
-----------------------------------
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
        Else
            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
0
 
LVL 10

Expert Comment

by:peetm
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.
0
 
LVL 81

Accepted Solution

by:
zorvek (Kevin Jones) earned 500 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.

Kevin
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

747 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now