I have seen a few posts about the need to pause an application while checking for an update then conditionally running the application after. I made a solution that works for me, hopefully it might workout for you too
1. I separated my application into a Launcher & application. The Launcher does the update check and application process start. I included some args to prevent my exe application from being started without the launcher.
2. to circumvent the need to close my application in the event if an install that would prompt for the application process to close, i first relocated my project file to a child folder than added a custom Action to move it to the root folder. The reason i did this is because the file location is then not part of the install register. The Custom Action is a 'Launch Attached File' and i created a .vbs to move the file. Here is the vbs code-
Code: Select all
Option Explicit
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
fso.MoveFile "C:\ProgramData\MyAppLocation\Files\Launcher.exe", "C:\ProgramData\MyAppLocation\"
3. create the Launcher. This contains the process of checking for an update, installing it if it exists then running the application after the install.
Launcher
Code: Select all
Private UpdateChecker As Timer
Private FilePath As String = String.Empty
Private NameOfUpdater As String = String.Empty
Private PathOfUpdater As String = String.Empty
'add any args like a matching code to check in your application MyApplication_Startup sub
'args are optional, can be 0, 1 or more and should have a space in between each arg
Private Arg1 As String = "123456" ' can be anything
Private Arg2 As String = "SomeOtherValidationCode"
Private Args As String = String.Join(CType(Arg1, String), " ", CType(Arg2, String))
Sub Launch()
'check to see if there are any updates pending
Dim p1 As Process = Process.Start(PathOfUpdater, "/justcheck")
p1.WaitForExit()
'Get the exit code for an update. 0 = update exists, <> = no update
Dim ret As Decimal = p1.ExitCode
'set a condition for if an update is found
Select Case ret
Case 0
'get the update and run it
Dim p2 As Process = Process.Start(PathOfUpdater, "/checknow -minuseractions")
p2.WaitForExit()
'because the updater is a separate process, your application wants to resume here
'so we put a timer to check the updater process and only proceed if it cant be found
UpdateChecker = New Timer
AddHandler UpdateChecker.Tick, AddressOf TimerEvent
UpdateChecker.Interval = CInt(TimeSpan.FromSeconds(1).TotalMilliseconds)
UpdateChecker.Start()
Case Else
'Run your application here as no updates were found
RunYourApplication()
End Select
End Sub
'This function runs a timer against the Updater process
'As long as the process <> 0, its running so wait
Private Shared Function TimerEvent(sender As Object, e As EventArgs) As Boolean
Dim retval As Boolean = False
Dim p() As Process = System.Diagnostics.Process.GetProcessesByName(NameOfUpdater)
If p.Length = 0 Then
UpdateChecker.Stop()
'run your application here now that the updater process has completed
RunYourApplication()
End If
Return retval
End Function
'This sub calls your application
Private Sub RunYourApplication()
Dim KLA As New Process()
KLA.StartInfo.FileName = FilePath 'path of executable file from above
KLA.StartInfo.Arguments = Args
KLA.Start()
End Sub
In the executable that is being updated, if you are passing args to validate or any other reason, here is what i do (in the ApplicationEvents class-
Code: Select all
Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As StartupEventArgs) Handles Me.Startup
'get the incoming args from the process.start in Launcher
Dim args As String() = System.Environment.GetCommandLineArgs
'separate the args string into separate args
'args(0) is always the path of the file so remains unused)
Dim GetArg1 As String = CType(args(1), String)
Dim GetArg2 As String = CType(args(2), String)
'Set some sort of validation that matches arg. example
Dim CheckArg1 As String = "123456"
If Not String.Compare(GetArg1, CheckArg1, False) = 0 Then
e.Cancel = True
End If
'if you get to here, your validation worked and your executable will open
End Sub
* you call you application launcher
* launcher checks for any updates
* if an update is found, launch the update and hold the the application until update is complete then launch the application
* if no update is found, launch the application
*optionally condition the process to make sure the application is run by the launcher only and not independently
Hope it helps, please feel free to update this or improve this code
Thanks
*UPDATE*
make sure that you properly declare your types when sending your args to the executable. The arg string being sent MUST all be string and they should be converted in the executable to the relative type. For example:
Setting up your args to send
Code: Select all
Dim arg1 As Integer = 123456
Dim arg2 As Boolean = False
Dim arg3 As String = "Some text to send"
'here i am converting all arg types to string and wrapping the conversions in a string convert to ensure i get a valid string
Dim ArgString As String = CType(String.Join(CType(arg1, String), " ", CType(arg2, String), " ", CType(arg3, String), String)
Dim KLA As New Process()
KLA.StartInfo.FileName = FilePath 'path of executable file from above
KLA.StartInfo.Arguments = ArgString
KLA.Start()
Code: Select all
'here i am converting the incoming args back to the original type
Dim GetArg1 As Integer = CType(args(1), Integer)
Dim GetArg2 As Boolean = CType(args(2), Boolean)
Dim GetArg3 As String = CType(args(2), String)