I'm trying to make it possible to run my project, copy itself to update.exe and then run that update.exe for the purpose of testing the update routine.
The problem I'm having is that the exefile is copied succesfully but when update.exe is then starts, it just always crashes.
If I abort the update.exe program from the crash, but my main exe still runs, I can then just start update.exe from explorer and all works fine. I can't for life figure out why update.exe crashes if it is started after it was copied from another exefile.
Here's the code:
Public Class Updater
Public sFullname As String
Public sExename As String
Public sArguments As String
Public Sub New()
'Constructor
Me.Initiate()
Me.FakeUpdate()
Me.DoUpdate()
'MsgBox(Me.sFullname)
End Sub
Private Sub Initiate()
Dim sCmdLine As String = Environment.CommandLine()
Dim iPos = sCmdLine.IndexOf("""", 2)
Me.sFullname = sCmdLine.Substring(1, iPos - 1).Trim()
Dim iPos2 = sFullname.LastIndexOf("\")
Me.sExename = sFullname.Substring(iPos2 1).Trim()
Me.sArguments = sCmdLine.Substring(iPos 1).Trim()
End Sub
Private Sub FakeUpdate()
'If we start the app with -fakeupdate parameter, copy myself to update.exe, then run update.exe to debug the update process.
If Me.sArguments = "-fakeupdate" Then
FileCopy(Me.sFullname, "update.exe")
Shell("update.exe")
End If
End Sub
Private Sub DoUpdate()
If Me.sExename = "update.exe" Then
MsgBox("DoUpdate called from update.exe")
End If
End Sub
End Class
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Updater As New Updater
End Sub
End Class
The project is configured that it runs with parameter -fakeupdate
The code is part of a larger project, but I have commented out all other code and still receive this error.
The error I'm getting from update.exe: Length cannot be less than null. Parametername: length
System.ArgumentOutOfRangeException: Length cannot be less than null.
Parameternaam: length
bij System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
bij Todo_List.Updater.Initiate() in S:\VB Projects\Todo List\Todo List\Form1.vb:regel 19
bij Todo_List.Updater..ctor() in S:\VB Projects\Todo List\Todo List\Form1.vb:regel 8
bij Todo_List.Form1.Form1_Load(Object sender, EventArgs e) in S:\VB Projects\Todo List\Todo List\Form1.vb:regel 594
bij System.EventHandler.Invoke(Object sender, EventArgs e)
bij System.Windows.Forms.Form.OnLoad(EventArgs e)
bij System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
bij System.Windows.Forms.Control.CreateControl()
bij System.Windows.Forms.Control.WmShowWindow(Message& m)
bij System.Windows.Forms.Control.WndProc(Message& m)
bij System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
bij System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
EDIT: small update, it also goes wrong if I don't even copy the file. Just shell("update.exe")
goes wrong. I even created a button on the form to launch it upon click and it fails every time. But if I run it from explorer, all is fine.
CodePudding user response:
This is weird behavior, possibly even a bug, but I figured it out.
Apparently, if you use shell ("program.exe")
to start a program, and from within that program, you call Environment.CommandLine()
it will just be program.exe, whereas if you doubleclick the program from explorer it will be C:\MyPath\program.exe instead.
In order to solve it, I had to change my code as follows:
Private Sub FakeUpdate()
Dim sShell As String
'If we start the app with -fakeupdate parameter, copy myself to update.exe, then run update.exe to debug the update process.
If Me.sArguments = "-fakeupdate" Then
FileCopy(Me.sFullname, "update.exe")
sShell = My.Computer.FileSystem.CurrentDirectory & "\update.exe"
Shell(sShell)
End If
End Sub
Now it works correctly, both from explorer AND from launching the program from within the program.