我有以下类用于磁盘分区和成像电脑。表单有一个常规文本框(tb1),它列出了进程的每一步(输出)和一个输出实时进程信息的富文本框(rtb1)。我遇到的问题是app在开始下一个子例程之前没有等待实时输出完成。见附件:
Imports System
Imports System.IO
Imports System.Management
Imports System.Text.RegularExpressions
Public Class Form1
Private Property pcSerial As Object = GetBiosSerialNumber()
Private Property title As String = "Ross PC Imaging"
Private Property pcModel As Object
Private Property wkstn As String
Private Property srvr As Object
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Call ross()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Call ross()
End Sub
Private Sub ross()
Dim objCS As ManagementObjectSearcher
Dim objMgmt As ManagementObject
objCS = New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
For Each objMgmt In objCS.Get
pcModel = objMgmt("model").ToString()
Next
Output(pcModel)
Output(pcSerial)
'Map network drive
Call MapDrive()
'Diskpart
Output("[ " & Now & " ] PC - " & pcSerial & " physical drives being partitioned and formatted")
If pcModel = "Server" Then
Call diskpart("srvr")
Else
Call diskpart("wkstn")
End If
Output("[ " & Now & " ] PC - " & pcSerial & " physical drives have been partitioned and formatted")
Dim msgDiskPart As String : msgDiskPart = ("[ " & Now & " ] PC - " & pcSerial & " physical drives partitioned and formatted")
Call WriteToLog(title, msgDiskPart)
'Dism
Output("[ " & Now & " ] PC - " & pcSerial & " imaging started")
If pcModel = "Server" Then
Call dism("srvr")
Else
Call dism("wkstn")
End If
Output("[ " & Now & " ] PC - " & pcSerial & " imaging completed")
Dim msgImgStop As String : msgImgStop = ("[ " & Now & " ] PC - " & pcSerial & " imaged")
Call WriteToLog(title, msgImgStop)
'Reboot
'Call reboot()
End Sub
Private Sub MapDrive()
'Map network drive
Dim map As New Process()
map.StartInfo.FileName = "net.exe"
map.StartInfo.Arguments = " use t: \\172.47.3.254\wims"
map.StartInfo.CreateNoWindow = True
map.StartInfo.UseShellExecute = False
map.StartInfo.RedirectStandardOutput = True
map.Start()
map.WaitForExit()
End Sub
Private Sub diskpart(ByVal pctype As String)
'Diskpart disk partitioning
Dim dp As New Process()
dp.StartInfo.FileName = "diskpart.exe"
dp.StartInfo.Arguments = " /s x:\" & pctype & "_diskpart.txt"
dp.StartInfo.CreateNoWindow = True
dp.StartInfo.UseShellExecute = False
dp.StartInfo.RedirectStandardOutput = True
dp.StartInfo.RedirectStandardError = True
dp.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dp.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dp.OutputDataReceived, AddressOf proc_OutputDataReceived
dp.Start()
dp.BeginErrorReadLine()
dp.BeginOutputReadLine()
End Sub
Private Sub dism(ByVal imgFile As String)
'Image C Drive
Dim dismC As New Process
dismC.StartInfo.FileName = "dism.exe"
dismC.StartInfo.Arguments = " /Apply-Image /ImageFile:t:\" & imgFile & ".wim /index:1 /ApplyDir:c:\"
dismC.StartInfo.CreateNoWindow = True
dismC.StartInfo.UseShellExecute = False
dismC.StartInfo.RedirectStandardOutput = True
dismC.StartInfo.RedirectStandardError = True
dismC.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dismC.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dismC.OutputDataReceived, AddressOf proc_OutputDataReceived
dismC.Start()
dismC.BeginErrorReadLine()
dismC.BeginOutputReadLine()
dismC.Close()
'Image D Drive
Dim dismD As New Process
dismD.StartInfo.FileName = "dism.exe"
dismD.StartInfo.Arguments = " /Apply-Image /ImageFile:t:\" & imgFile & ".wim /index:2 /ApplyDir:d:\"
dismD.StartInfo.CreateNoWindow = True
dismD.StartInfo.UseShellExecute = False
dismD.StartInfo.RedirectStandardOutput = True
dismD.StartInfo.RedirectStandardError = True
dismD.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dismD.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dismD.OutputDataReceived, AddressOf proc_OutputDataReceived
dismD.Start()
dismD.BeginErrorReadLine()
dismD.BeginOutputReadLine()
dismD.Close()
End Sub
Private Sub reboot()
'Reboots a pc while in WinPE
Dim reset As New Process
reset.StartInfo.FileName = "wpeutils.exe"
reset.StartInfo.Arguments = " reboot"
reset.Start()
End Sub
Private Sub WriteToLog(ByVal title As String, ByVal msg As String)
'Check and make directory
If Not System.IO.Directory.Exists("t:\logs\") Then
System.IO.Directory.CreateDirectory("t:\logs\")
End If
'Check and make file
Dim fs As FileStream = New FileStream("t:\logs\" & pcSerial & ".log", FileMode.OpenOrCreate, FileAccess.ReadWrite)
Dim s As StreamWriter = New StreamWriter(fs)
s.Close()
fs.Close()
'Logging
Dim fs1 As FileStream = New FileStream("t:\logs\" & pcSerial & ".log", FileMode.Append, FileAccess.Write)
Dim s1 As StreamWriter = New StreamWriter(fs1)
s1.Write("Title: " & title & vbCrLf)
s1.Write("Message: " & msg & vbCrLf)
s1.Write("================================================" & vbCrLf)
s1.Close()
fs1.Close()
End Sub
Private Sub Output(s As String)
'Output to form window
If s <> "" Then
tb1.AppendText(vbCrLf & ">> " & s)
End If
End Sub
Public ReadOnly Property Model()
Get
Model = pcModel
End Get
End Property
Public Function GetBiosSerialNumber() As String
Dim OutputString As String = String.Empty
Using Process As New Process
AddHandler Process.OutputDataReceived,
Sub(sender As Object, e As DataReceivedEventArgs)
OutputString = OutputString & e.Data & vbCrLf
End Sub
With Process.StartInfo
.FileName = "cmd"
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardInput = True
.RedirectStandardOutput = True
.RedirectStandardError = True
End With
With Process
.Start()
.BeginOutputReadLine()
End With
Using InputStream As System.IO.StreamWriter = Process.StandardInput
With InputStream
.AutoFlush = True
.Write("wmic bios get serialnumber" & vbCrLf)
End With
End Using
Do
Application.DoEvents()
Loop Until Process.HasExited
End Using
Return Replace(OutputString.Split(CChar(vbCrLf)).ToList(6).Substring(1), " ", "")
End Function
Delegate Sub UpdateTextBoxDelg(text As String)
Public myDelegate As UpdateTextBoxDelg = New UpdateTextBoxDelg(AddressOf UpdateTextBox)
Public Sub UpdateTextBox(text As String)
rtb1.Text += text & Environment.NewLine
rtb1.SelectionStart = rtb1.Text.Length
rtb1.ScrollToCaret()
End Sub
Public Sub proc_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
If Me.InvokeRequired = True Then
Me.Invoke(myDelegate, e.Data)
Else
UpdateTextBox(e.Data)
End If
End Sub
结束班
我感谢任何建议。
答案 0 :(得分:0)
Imports System
Imports System.IO
Imports System.Management
Imports System.Text.RegularExpressions
Public Class Form1
Delegate Sub UpdateTextBoxDelg(text As String)
Public myDelegate As UpdateTextBoxDelg = New UpdateTextBoxDelg(AddressOf UpdateTextBox)
Private Property pcSerial As Object = GetBiosSerialNumber()
Private Property title As String = "Ross PC Imaging"
Private Property pcModel As Object
Private Property wkstn As String
Private Property srvr As Object
Private Property pctype As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call ross()
End Sub
Private Sub ross()
Dim objCS As ManagementObjectSearcher
Dim objMgmt As ManagementObject
objCS = New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
For Each objMgmt In objCS.Get
pcModel = objMgmt("model").ToString()
Next
Output(pcModel)
Output(pcSerial)
'Map network drive
DriveMap.RunWorkerAsync()
End Sub
Private Sub DriveMap_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles DriveMap.DoWork
'Map network drive
Dim map As New Process()
map.StartInfo.FileName = "net.exe"
map.StartInfo.Arguments = " use t: \\172.47.3.254\wims"
map.StartInfo.CreateNoWindow = True
map.StartInfo.UseShellExecute = False
map.StartInfo.RedirectStandardOutput = True
map.Start()
map.WaitForExit()
End Sub
Private Sub DriveMap_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles DriveMap.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - partitioning and formatting drives")
Dim msgDiskPart As String : msgDiskPart = ("[ " & Now & " ] PC - *" & pcSerial & "* - partitioning and formatting drives")
Call WriteToLog(title, msgDiskPart)
DiskPart.RunWorkerAsync()
End Sub
Private Sub DiskPart_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles DiskPart.DoWork
If pcModel = "Server" Then
pctype = "srvr"
Else
pctype = "wkstn"
End If
'Diskpart disk partitioning
Dim dp As New Process()
dp.StartInfo.FileName = "diskpart.exe"
dp.StartInfo.Arguments = " /s x:\" & pctype & "_diskpart.txt"
dp.StartInfo.CreateNoWindow = True
dp.StartInfo.UseShellExecute = False
dp.StartInfo.RedirectStandardOutput = True
dp.StartInfo.RedirectStandardError = True
dp.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dp.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dp.OutputDataReceived, AddressOf proc_OutputDataReceived
dp.Start()
dp.BeginErrorReadLine()
dp.BeginOutputReadLine()
dp.WaitForExit()
End Sub
Private Sub DiskPart_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles DiskPart.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - drives have been partitioned and formatted")
Dim msgDiskPart As String : msgDiskPart = ("[ " & Now & " ] PC - *" & pcSerial & "* - drives have been partitioned and formatted")
Call WriteToLog(title, msgDiskPart)
Output("[ " & Now & " ] PC - *" & pcSerial & "* - running disk check on drive C")
Dim msgChkDskC As String : msgChkDskC = ("[ " & Now & " ] PC - *" & pcSerial & "* - running disk check on drive C")
Call WriteToLog(title, msgChkDskC)
ChkDskC.RunWorkerAsync()
End Sub
Private Sub ChkDskC_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles ChkDskC.DoWork
Dim dc As New Process
dc.StartInfo.FileName = "chkdsk.exe"
dc.StartInfo.Arguments = " c: /f"
dc.StartInfo.CreateNoWindow = True
dc.StartInfo.UseShellExecute = False
dc.StartInfo.RedirectStandardOutput = True
dc.StartInfo.RedirectStandardError = True
dc.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dc.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dc.OutputDataReceived, AddressOf proc_OutputDataReceived
dc.Start()
dc.BeginErrorReadLine()
dc.BeginOutputReadLine()
dc.WaitForExit()
End Sub
Private Sub ChkDskC_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles ChkDskC.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - drive C had no errors")
Dim msgChkDskC As String : msgChkDskC = ("[ " & Now & " ] PC - *" & pcSerial & "* - drive C had no errors")
Call WriteToLog(title, msgChkDskC)
Output("[ " & Now & " ] PC - *" & pcSerial & "* - running disk check on drive D")
Dim msgChkDskD As String : msgChkDskD = ("[ " & Now & " ] PC - *" & pcSerial & "* - running disk check on drive D")
Call WriteToLog(title, msgChkDskD)
ChkDskD.RunWorkerAsync()
End Sub
Private Sub ChkDskD_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles ChkDskD.DoWork
Dim dc As New Process
dc.StartInfo.FileName = "chkdsk.exe"
dc.StartInfo.Arguments = " d: /f"
dc.StartInfo.CreateNoWindow = True
dc.StartInfo.UseShellExecute = False
dc.StartInfo.RedirectStandardOutput = True
dc.StartInfo.RedirectStandardError = True
dc.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dc.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dc.OutputDataReceived, AddressOf proc_OutputDataReceived
dc.Start()
dc.BeginErrorReadLine()
dc.BeginOutputReadLine()
dc.WaitForExit()
End Sub
Private Sub ChkDskD_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles ChkDskD.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - drive D had no errors")
Dim msgChkDskD As String : msgChkDskD = ("[ " & Now & " ] PC - *" & pcSerial & "* - drive D had no errors")
Call WriteToLog(title, msgChkDskD)
Output("[ " & Now & " ] PC - *" & pcSerial & "* - imaging C drive")
Dim msgDismC As String : msgDismC = ("[ " & Now & " ] PC - *" & pcSerial & "* - imaging C drive")
Call WriteToLog(title, msgDismC)
DismC.RunWorkerAsync()
End Sub
Private Sub DismC_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles DismC.DoWork
If pcModel = "Server" Then
pctype = "srvr"
Else
pctype = "wkstn"
End If
'Image C Drive
Dim dismC As New Process
dismC.StartInfo.FileName = "dism.exe"
dismC.StartInfo.Arguments = " /Apply-Image /ImageFile:t:\" & pctype & ".wim /index:1 /ApplyDir:c:\"
dismC.StartInfo.CreateNoWindow = True
dismC.StartInfo.UseShellExecute = False
dismC.StartInfo.RedirectStandardOutput = True
dismC.StartInfo.RedirectStandardError = True
dismC.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dismC.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dismC.OutputDataReceived, AddressOf proc_OutputDataReceived
dismC.Start()
dismC.BeginErrorReadLine()
dismC.BeginOutputReadLine()
dismC.WaitForExit()
End Sub
Private Sub DismC_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles DismC.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - drive C imaged")
Dim msgDismC As String : msgDismC = ("[ " & Now & " ] PC - *" & pcSerial & "* - drive C imaged")
Call WriteToLog(title, msgDismC)
Output("[ " & Now & " ] PC - *" & pcSerial & "* - imaging D drive")
Dim msgDismD As String : msgDismD = ("[ " & Now & " ] PC - *" & pcSerial & "* - imaging D drive")
Call WriteToLog(title, msgDismD)
DismD.RunWorkerAsync()
End Sub
Private Sub DismD_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles DismD.DoWork
If pcModel = "Server" Then
pctype = "srvr"
Else
pctype = "wkstn"
End If
'Image D Drive
Dim dismD As New Process
dismD.StartInfo.FileName = "dism.exe"
dismD.StartInfo.Arguments = " /Apply-Image /ImageFile:t:\" & pctype & ".wim /index:2 /ApplyDir:d:\"
dismD.StartInfo.CreateNoWindow = True
dismD.StartInfo.UseShellExecute = False
dismD.StartInfo.RedirectStandardOutput = True
dismD.StartInfo.RedirectStandardError = True
dismD.EnableRaisingEvents = True
Application.DoEvents()
AddHandler dismD.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler dismD.OutputDataReceived, AddressOf proc_OutputDataReceived
dismD.Start()
dismD.BeginErrorReadLine()
dismD.BeginOutputReadLine()
dismD.WaitForExit()
End Sub
Private Sub DismD_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles DismD.RunWorkerCompleted
Output("[ " & Now & " ] PC - *" & pcSerial & "* - drive D imaged")
Dim msgDismD As String : msgDismD = ("[ " & Now & " ] PC - *" & pcSerial & "* - drive D imaged")
Call WriteToLog(title, msgDismD)
Output("[ " & Now & " ] PC - *" & pcSerial & "* - imaging complete, rebooting")
'Call reboot()
End Sub
Private Sub reboot()
'Reboots a pc while in WinPE
Dim reset As New Process
reset.StartInfo.FileName = "wpeutils.exe"
reset.StartInfo.Arguments = " shutdown"
reset.Start()
End Sub
Private Sub WriteToLog(ByVal title As String, ByVal msg As String)
'Check and make directory
If Not System.IO.Directory.Exists("t:\logs\") Then
System.IO.Directory.CreateDirectory("t:\logs\")
End If
'Check and make file
Dim fs As FileStream = New FileStream("t:\logs\" & pcSerial & ".log", FileMode.OpenOrCreate, FileAccess.ReadWrite)
Dim s As StreamWriter = New StreamWriter(fs)
s.Close()
fs.Close()
'Logging
Dim fs1 As FileStream = New FileStream("t:\logs\" & pcSerial & ".log", FileMode.Append, FileAccess.Write)
Dim s1 As StreamWriter = New StreamWriter(fs1)
s1.Write("Title: " & title & vbCrLf)
s1.Write("Message: " & msg & vbCrLf)
s1.Write("================================================" & vbCrLf)
s1.Close()
fs1.Close()
End Sub
Private Sub Output(s As String)
'Output to form window
If s <> "" Then
tb1.AppendText(vbCrLf & ">> " & s)
End If
End Sub
Public ReadOnly Property Model()
Get
Model = pcModel
End Get
End Property
Public Function GetBiosSerialNumber() As String
Dim OutputString As String = String.Empty
Using Process As New Process
AddHandler Process.OutputDataReceived,
Sub(sender As Object, e As DataReceivedEventArgs)
OutputString = OutputString & e.Data & vbCrLf
End Sub
With Process.StartInfo
.FileName = "cmd"
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardInput = True
.RedirectStandardOutput = True
.RedirectStandardError = True
End With
With Process
.Start()
.BeginOutputReadLine()
End With
Using InputStream As System.IO.StreamWriter = Process.StandardInput
With InputStream
.AutoFlush = True
.Write("wmic bios get serialnumber" & vbCrLf)
End With
End Using
Do
Application.DoEvents()
Loop Until Process.HasExited
End Using
Return Replace(OutputString.Split(CChar(vbCrLf)).ToList(6).Substring(1), " ", "")
End Function
Public Sub UpdateTextBox(text As String)
rtb1.Text += text & Environment.NewLine
rtb1.SelectionStart = rtb1.Text.Length
rtb1.ScrollToCaret()
End Sub
Public Sub proc_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
If Me.InvokeRequired = True Then
Me.Invoke(myDelegate, e.Data)
Else
UpdateTextBox(e.Data)
End If
End Sub
结束班