VB.NET 复制自己然后 运行 复制失败
VB.NET Copying myself and then run the copy fails
我正在尝试 运行 我的项目,将其自身复制到 update.exe 然后 运行 update.exe 以测试更新常规。
我遇到的问题是 exe 文件已成功复制,但是当 update.exe 启动时,它总是崩溃。
如果我从崩溃中中止 update.exe 程序,但我的主 exe 仍然是 运行,我可以从资源管理器中启动 update.exe 并且一切正常。如果从另一个 exe 文件复制后启动它,我终生无法弄清楚为什么 update.exe 会崩溃。
代码如下:
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
项目配置为 运行s 带有参数 -fakeupdate
该代码是一个更大项目的一部分,但我已注释掉所有其他代码,但仍然收到此错误。
我从 update.exe 得到的错误:长度不能小于 null。参数名称:长度
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)
编辑:小更新,如果我什至不复制文件也会出错。只是 shell("update.exe")
出错了。我什至在表单上创建了一个按钮以在单击时启动它,但每次都失败。但是如果我 运行 它来自资源管理器,一切都很好。
这是一个奇怪的行为,甚至可能是一个错误,但我想通了。
显然,如果您使用 shell ("program.exe")
启动一个程序,并从该程序中调用 Environment.CommandLine()
,它将只是 program.exe,而如果您双击该程序explorer 它将改为 C:\MyPath\program.exe。
为了解决这个问题,我不得不按如下方式更改我的代码:
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
现在它可以正常工作,无论是从资源管理器还是从程序内部启动程序。
我正在尝试 运行 我的项目,将其自身复制到 update.exe 然后 运行 update.exe 以测试更新常规。
我遇到的问题是 exe 文件已成功复制,但是当 update.exe 启动时,它总是崩溃。
如果我从崩溃中中止 update.exe 程序,但我的主 exe 仍然是 运行,我可以从资源管理器中启动 update.exe 并且一切正常。如果从另一个 exe 文件复制后启动它,我终生无法弄清楚为什么 update.exe 会崩溃。
代码如下:
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
项目配置为 运行s 带有参数 -fakeupdate
该代码是一个更大项目的一部分,但我已注释掉所有其他代码,但仍然收到此错误。
我从 update.exe 得到的错误:长度不能小于 null。参数名称:长度
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)
编辑:小更新,如果我什至不复制文件也会出错。只是 shell("update.exe")
出错了。我什至在表单上创建了一个按钮以在单击时启动它,但每次都失败。但是如果我 运行 它来自资源管理器,一切都很好。
这是一个奇怪的行为,甚至可能是一个错误,但我想通了。
显然,如果您使用 shell ("program.exe")
启动一个程序,并从该程序中调用 Environment.CommandLine()
,它将只是 program.exe,而如果您双击该程序explorer 它将改为 C:\MyPath\program.exe。
为了解决这个问题,我不得不按如下方式更改我的代码:
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
现在它可以正常工作,无论是从资源管理器还是从程序内部启动程序。