DOBON.NETプログラミング道掲示板

No34644 の記事


■34644 / )  Re[1]: VB.net非同期処理でtextboxに出力したい
□投稿者/ 魔界の仮面弁士 大御所(1314回)-(2021/02/12(Fri) 11:00:27)
  • アイコン
    No34642に返信(ゆきさんの記事)
    > 調べたところデリゲート処理が必要らしいのですがどのように改定いうかわかりません。
    
    たとえばこんな感じ。
    
    Public Class Form1
        Private WithEvents proc As Process
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            If Me.components Is Nothing Then
                Me.components = New System.ComponentModel.Container()
            End If
            Button1.Text = "開始"
            Button2.Text = "標準入力を渡す"
            Button2.Enabled = False
            'コマンド
            TextBox1.Text = Environment.GetEnvironmentVariable("ComSpec")
            '引数
            TextBox2.Text = ""
            '標準入力の内容
            TextBox3.Text = "DIR /D ""C:\Program Files (x86)\"""
            '標準出力 & 標準エラー出力
            RichTextBox1.ReadOnly = True
            RichTextBox1.BackColor = Color.Black
            RichTextBox1.ForeColor = Color.White
            RichTextBox1.ScrollBars = RichTextBoxScrollBars.Both
            RichTextBox1.WordWrap = False
            RichTextBox1.HideSelection = False
        End Sub
        Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Button1.Enabled = False
            TextBox1.ReadOnly = True
            TextBox2.ReadOnly = True
            RichTextBox1.Clear()
            Button2.Enabled = True
            proc = Process.Start(New ProcessStartInfo(TextBox1.Text, TextBox2.Text) With
            {
                .UseShellExecute = False,
                .CreateNoWindow = True,
                .RedirectStandardInput = True,
                .RedirectStandardOutput = True,
                .RedirectStandardError = True
            })
            Me.components.Add(proc)
            proc.BeginOutputReadLine()
            proc.BeginErrorReadLine()
            Await Task.Run(AddressOf proc.WaitForExit)
            proc.Close()
            Me.components.Remove(proc)
            TextBox1.ReadOnly = False
            TextBox2.ReadOnly = False
            Button2.Enabled = False
            Button1.Enabled = True
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If proc IsNot Nothing Then
                proc.StandardInput.Write(TextBox3.Text & vbLf)
            Else
                Debug.WriteLine("既に閉じられている")
            End If
        End Sub
        Private Sub proc_OutputDataReceived(sender As Object, e As DataReceivedEventArgs) Handles proc.OutputDataReceived
            StandardOut(e.Data, isError:=False)
        End Sub
        Private Sub proc_ErrorDataReceived(sender As Object, e As DataReceivedEventArgs) Handles proc.ErrorDataReceived
            StandardOut(e.Data, isError:=True)
        End Sub
        Private Sub StandardOut(message As String, isError As Boolean)
            Invoke(
                New MethodInvoker(
                   Sub()
                       Dim s = RichTextBox1.TextLength
                       Dim l = If(message?.Length, 0)
                       RichTextBox1.SelectionStart = s
                       RichTextBox1.SelectedText = If(message, "")
                       RichTextBox1.Select(s, l)
                       RichTextBox1.SelectionColor = If(isError, Color.Yellow, RichTextBox1.ForeColor)
                       RichTextBox1.SelectionBackColor = If(isError, Color.Red, RichTextBox1.BackColor)
                       RichTextBox1.SelectionStart = RichTextBox1.TextLength
                       RichTextBox1.SelectedText = vbCr
                   End Sub
                )
            )
        End Sub
    End Class
    
    
    ただし、標準出力された内容の末尾が改行で無いと
    OutputDataReceived イベントが発生しない点にご注意ください。
    
    「TIME /T」の結果は改行が来るのですぐに表示されますが、
    「TIME」は改行を伴わないため、次の応答が来るまでイベントが発生しません。
    
    「PAUSE」コマンドなどとも相性が悪いですね。

違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -