Home > Enterprise >  VB.NET Copying myself and then run the copy fails
VB.NET Copying myself and then run the copy fails

Time:04-01

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.

  • Related