0
나는 diskparting 및 이미징 PC를위한 다음과 같은 클래스가 있습니다. 이 양식에는 프로세스의 각 단계 (출력)를 나열하는 일반 텍스트 상자 (tb1)와 실시간 프로세스 정보를 출력하는 리치 텍스트 상자 (rtb1)가 있습니다. 내가 겪고있는 문제는 앱이 다음 서브 루틴을 시작하기 전에 실시간 출력이 끝나기를 기다리지 않고 있다는 것입니다. 내가 어떤 조언을 주셔서 감사합니다vb.net에서 프로세스의 실시간 출력
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
최종 클래스
: 연결 코드를 참조하십시오.
당신이 프로세스를 산란 한 다음 기다리고있어 같이 여러 번 당신의 UI 스레드를 차단하고 있습니다. 백그라운드 작업을 수행하려면 별도의 스레드를 사용해야합니다. – xxbbcc
용서해주세요. 나는 여전히 vb.net을 처음 사용합니다. 어떻게 그들을 별도의 스레드로 만들 수 있습니까? –
그리고 그것은 실제로 배경 작업이 아닙니다. 1 프로세스가 다음 호출 전에 완료되어야합니다. –