2

こんにちは私はVB.NETプロジェクトで使用したいc#で書かれた素晴らしいクラスを見つけました。

私はこのスレッドでそれを見つけました: C#:コンソールアプリケーションの出力をリダイレクトする:出力をフラッシュする方法は?

C#クラスは次のようになります。

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;

namespace System.Diagnostics
{
    internal delegate void UserCallBack(string data);
    public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);

    public class FixedProcess : Process
    {
        internal AsyncStreamReader output;
        internal AsyncStreamReader error;
        public event DataReceivedEventHandler OutputDataReceived;
        public event DataReceivedEventHandler ErrorDataReceived;

        public new void BeginOutputReadLine()
        {
            Stream baseStream = StandardOutput.BaseStream;
            this.output = new AsyncStreamReader(this, baseStream, new UserCallBack(this.FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
            this.output.BeginReadLine();
        }

        public void BeginErrorReadLine()
        {
            Stream baseStream = StandardError.BaseStream;
            this.error = new AsyncStreamReader(this, baseStream, new UserCallBack(this.FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
            this.error.BeginReadLine();
        }

        internal void FixedOutputReadNotifyUser(string data)
        {
            DataReceivedEventHandler outputDataReceived = this.OutputDataReceived;
            if (outputDataReceived != null)
            {
                DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
                if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired)
                {
                    this.SynchronizingObject.Invoke(outputDataReceived, new object[]
                    {
                        this, 
                        dataReceivedEventArgs
                    });
                    return;
                }
                outputDataReceived(this, dataReceivedEventArgs);
            }
        }

        internal void FixedErrorReadNotifyUser(string data)
        {
            DataReceivedEventHandler errorDataReceived = this.ErrorDataReceived;
            if (errorDataReceived != null)
            {
                DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
                if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired)
                {
                    this.SynchronizingObject.Invoke(errorDataReceived, new object[]
                    {
                        this, 
                        dataReceivedEventArgs
                    });
                    return;
                }
                errorDataReceived(this, dataReceivedEventArgs);
            }
        }
    }

    internal class AsyncStreamReader : IDisposable
    {
        internal const int DefaultBufferSize = 1024;
        private const int MinBufferSize = 128;
        private Stream stream;
        private Encoding encoding;
        private Decoder decoder;
        private byte[] byteBuffer;
        private char[] charBuffer;
        private int _maxCharsPerBuffer;
        private Process process;
        private UserCallBack userCallBack;
        private bool cancelOperation;
        private ManualResetEvent eofEvent;
        private Queue messageQueue;
        private StringBuilder sb;
        private bool bLastCarriageReturn;
        public virtual Encoding CurrentEncoding
        {
            get
            {
                return this.encoding;
            }
        }
        public virtual Stream BaseStream
        {
            get
            {
                return this.stream;
            }
        }
        internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding)
            : this(process, stream, callback, encoding, 1024)
        {
        }
        internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
        {
            this.Init(process, stream, callback, encoding, bufferSize);
            this.messageQueue = new Queue();
        }
        private void Init(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
        {
            this.process = process;
            this.stream = stream;
            this.encoding = encoding;
            this.userCallBack = callback;
            this.decoder = encoding.GetDecoder();
            if (bufferSize < 128)
            {
                bufferSize = 128;
            }
            this.byteBuffer = new byte[bufferSize];
            this._maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize);
            this.charBuffer = new char[this._maxCharsPerBuffer];
            this.cancelOperation = false;
            this.eofEvent = new ManualResetEvent(false);
            this.sb = null;
            this.bLastCarriageReturn = false;
        }
        public virtual void Close()
        {
            this.Dispose(true);
        }
        void IDisposable.Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing && this.stream != null)
            {
                this.stream.Close();
            }
            if (this.stream != null)
            {
                this.stream = null;
                this.encoding = null;
                this.decoder = null;
                this.byteBuffer = null;
                this.charBuffer = null;
            }
            if (this.eofEvent != null)
            {
                this.eofEvent.Close();
                this.eofEvent = null;
            }
        }
        internal void BeginReadLine()
        {
            if (this.cancelOperation)
            {
                this.cancelOperation = false;
            }
            if (this.sb == null)
            {
                this.sb = new StringBuilder(1024);
                this.stream.BeginRead(this.byteBuffer, 0, this.byteBuffer.Length, new AsyncCallback(this.ReadBuffer), null);
                return;
            }
            this.FlushMessageQueue();
        }
        internal void CancelOperation()
        {
            this.cancelOperation = true;
        }
        private void ReadBuffer(IAsyncResult ar)
        {
            int num;
            try
            {
                num = this.stream.EndRead(ar);
            }
            catch (IOException)
            {
                num = 0;
            }
            catch (OperationCanceledException)
            {
                num = 0;
            }
            if (num == 0)
            {
                lock (this.messageQueue)
                {
                    if (this.sb.Length != 0)
                    {
                        this.messageQueue.Enqueue(this.sb.ToString());
                        this.sb.Length = 0;
                    }
                    this.messageQueue.Enqueue(null);
                }
                try
                {
                    this.FlushMessageQueue();
                    return;
                }
                finally
                {
                    this.eofEvent.Set();
                }
            }
            int chars = this.decoder.GetChars(this.byteBuffer, 0, num, this.charBuffer, 0);
            this.sb.Append(this.charBuffer, 0, chars);
            this.GetLinesFromStringBuilder();
            this.stream.BeginRead(this.byteBuffer, 0, this.byteBuffer.Length, new AsyncCallback(this.ReadBuffer), null);
        }
        private void GetLinesFromStringBuilder()
        {
            int i = 0;
            int num = 0;
            int length = this.sb.Length;
            if (this.bLastCarriageReturn && length > 0 && this.sb[0] == '\n')
            {
                i = 1;
                num = 1;
                this.bLastCarriageReturn = false;
            }
            while (i < length)
        {
            char c = this.sb[i];
            if (c == '\r' || c == '\n')
            {
                if (c == '\r' && i + 1 < length && this.sb[i + 1] == '\n')
                {
                    i++;
                }

                string obj = this.sb.ToString(num, i + 1 - num);

                num = i + 1;

                lock (this.messageQueue)
                {
                    this.messageQueue.Enqueue(obj);
                }
            }
            i++;
        }

            // Flush Fix: Send Whatever is left in the buffer
            string endOfBuffer = this.sb.ToString(num, length - num);
            lock (this.messageQueue)
            {
                this.messageQueue.Enqueue(endOfBuffer);
                num = length;
            }
            // End Flush Fix

            if (this.sb[length - 1] == '\r')
            {
                this.bLastCarriageReturn = true;
            }
            if (num < length)
            {
                this.sb.Remove(0, num);
            }
            else
            {
                this.sb.Length = 0;
            }
            this.FlushMessageQueue();
        }
        private void FlushMessageQueue()
        {
            while (this.messageQueue.Count > 0)
            {
                lock (this.messageQueue)
                {
                    if (this.messageQueue.Count > 0)
                    {
                        string data = (string)this.messageQueue.Dequeue();
                        if (!this.cancelOperation)
                        {
                            this.userCallBack(data);
                        }
                    }
                    continue;
                }
                break;
            }
        }
        internal void WaitUtilEOF()
        {
            if (this.eofEvent != null)
            {
                this.eofEvent.WaitOne();
                this.eofEvent.Close();
                this.eofEvent = null;
            }
        }
    }

    public class DataReceivedEventArgs : EventArgs
    {
        internal string _data;
        /// <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
        /// <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
        /// <filterpriority>2</filterpriority>
        public string Data
        {
            get
            {
                return this._data;
            }
        }
        internal DataReceivedEventArgs(string data)
        {
            this._data = data;
        }
    }
}

私の変換されたコードは次のようになります:

Imports System
Imports System.Collections
Imports System.IO
Imports System.Text
Imports System.Threading

Namespace System.Diagnostics
    Friend Delegate Sub UserCallBack(data As String)
    Public Delegate Sub DataReceivedEventHandler(sender As Object, e As DataReceivedEventArgs)

    Public Class FixedProcess
        Inherits Process
        Friend output As AsyncStreamReader
        Friend [error] As AsyncStreamReader
        Public Event OutputDataReceived As DataReceivedEventHandler '<----------Error 1
        Public Event ErrorDataReceived As DataReceivedEventHandler '<------------Error 2

        Public Shadows Sub BeginOutputReadLine()
            Dim baseStream As Stream = StandardOutput.BaseStream
            Me.output = New AsyncStreamReader(Me, baseStream, New UserCallBack(AddressOf Me.FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding)
            Me.output.BeginReadLine()
        End Sub

        Public Sub BeginErrorReadLine()   '<-------------Error 3
            Dim baseStream As Stream = StandardError.BaseStream
            Me.[error] = New AsyncStreamReader(Me, baseStream, New UserCallBack(AddressOf Me.FixedErrorReadNotifyUser), StandardError.CurrentEncoding)
            Me.[error].BeginReadLine()
        End Sub

        Friend Sub FixedOutputReadNotifyUser(data As String)

            Dim outputDataReceived As DataReceivedEventHandler = Me.OutputDataReceived '<------------Error 4
            If outputDataReceived IsNot Nothing Then
                Dim dataReceivedEventArgs As New DataReceivedEventArgs(data)
                If Me.SynchronizingObject IsNot Nothing AndAlso Me.SynchronizingObject.InvokeRequired Then
                    Me.SynchronizingObject.Invoke(outputDataReceived, New Object() {Me, dataReceivedEventArgs})
                    Return
                End If
                outputDataReceived(Me, dataReceivedEventArgs)
            End If
        End Sub

        Friend Sub FixedErrorReadNotifyUser(data As String)
            Dim errorDataReceived As DataReceivedEventHandler = Me.ErrorDataReceived '<-------------Error 5
            If errorDataReceived IsNot Nothing Then
                Dim dataReceivedEventArgs As New DataReceivedEventArgs(data)
                If Me.SynchronizingObject IsNot Nothing AndAlso Me.SynchronizingObject.InvokeRequired Then
                    Me.SynchronizingObject.Invoke(errorDataReceived, New Object() {Me, dataReceivedEventArgs})
                    Return
                End If
                errorDataReceived(Me, dataReceivedEventArgs)
            End If
        End Sub
    End Class

    Friend Class AsyncStreamReader
        Implements IDisposable
        Friend Const DefaultBufferSize As Integer = 1024
        Private Const MinBufferSize As Integer = 128
        Private stream As Stream
        Private encoding As Encoding
        Private decoder As Decoder
        Private byteBuffer As Byte()
        Private charBuffer As Char()
        Private _maxCharsPerBuffer As Integer
        Private process As Process
        Private userCallBack As UserCallBack
        Private cancelOperation As Boolean
        Private eofEvent As ManualResetEvent
        Private messageQueue As Queue
        Private sb As StringBuilder
        Private bLastCarriageReturn As Boolean
        Public Overridable ReadOnly Property CurrentEncoding() As Encoding
            Get
                Return Me.encoding
            End Get
        End Property
        Public Overridable ReadOnly Property BaseStream() As Stream
            Get
                Return Me.stream
            End Get
        End Property
        Friend Sub New(process As Process, stream As Stream, callback As UserCallBack, encoding As Encoding)
            Me.New(process, stream, callback, encoding, 1024)
        End Sub
        Friend Sub New(process As Process, stream As Stream, callback As UserCallBack, encoding As Encoding, bufferSize As Integer)
            Me.Init(process, stream, callback, encoding, bufferSize)
            Me.messageQueue = New Queue()
        End Sub
        Private Sub Init(process As Process, stream As Stream, callback As UserCallBack, encoding As Encoding, bufferSize As Integer)
            Me.process = process
            Me.stream = stream
            Me.encoding = encoding
            Me.userCallBack = callback
            Me.decoder = encoding.GetDecoder()
            If bufferSize < 128 Then
                bufferSize = 128
            End If
            Me.byteBuffer = New Byte(bufferSize - 1) {}
            Me._maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize)
            Me.charBuffer = New Char(Me._maxCharsPerBuffer - 1) {}
            Me.cancelOperation = False
            Me.eofEvent = New ManualResetEvent(False)
            Me.sb = Nothing
            Me.bLastCarriageReturn = False
        End Sub
        Public Overridable Sub Close()
            Me.Dispose(True)
        End Sub
        Private Sub IDisposable_Dispose() Implements IDisposable.Dispose
            Me.Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
        Protected Overridable Sub Dispose(disposing As Boolean)
            If disposing AndAlso Me.stream IsNot Nothing Then
                Me.stream.Close()
            End If
            If Me.stream IsNot Nothing Then
                Me.stream = Nothing
                Me.encoding = Nothing
                Me.decoder = Nothing
                Me.byteBuffer = Nothing
                Me.charBuffer = Nothing
            End If
            If Me.eofEvent IsNot Nothing Then
                Me.eofEvent.Close()
                Me.eofEvent = Nothing
            End If
        End Sub
        Friend Sub BeginReadLine()
            If Me.cancelOperation Then
                Me.cancelOperation = False
            End If
            If Me.sb Is Nothing Then
                Me.sb = New StringBuilder(1024)
                Me.stream.BeginRead(Me.byteBuffer, 0, Me.byteBuffer.Length, New AsyncCallback(AddressOf Me.ReadBuffer), Nothing)
                Return
            End If
            Me.FlushMessageQueue()
        End Sub
        Friend Sub CancelOperation()  '<------- Error 6
            Me.cancelOperation = True
        End Sub
        Private Sub ReadBuffer(ar As IAsyncResult)
            Dim num As Integer
            Try
                num = Me.stream.EndRead(ar)
            Catch generatedExceptionName As IOException
                num = 0
            Catch generatedExceptionName As OperationCanceledException
                num = 0
            End Try
            If num = 0 Then
                SyncLock Me.messageQueue
                    If Me.sb.Length <> 0 Then
                        Me.messageQueue.Enqueue(Me.sb.ToString())
                        Me.sb.Length = 0
                    End If
                    Me.messageQueue.Enqueue(Nothing)
                End SyncLock
                Try
                    Me.FlushMessageQueue()
                    Return
                Finally
                    Me.eofEvent.[Set]()
                End Try
            End If
            Dim chars As Integer = Me.decoder.GetChars(Me.byteBuffer, 0, num, Me.charBuffer, 0)
            Me.sb.Append(Me.charBuffer, 0, chars)
            Me.GetLinesFromStringBuilder()
            Me.stream.BeginRead(Me.byteBuffer, 0, Me.byteBuffer.Length, New AsyncCallback(AddressOf Me.ReadBuffer), Nothing)
        End Sub
        Private Sub GetLinesFromStringBuilder()
            Dim i As Integer = 0
            Dim num As Integer = 0
            Dim length As Integer = Me.sb.Length
            If Me.bLastCarriageReturn AndAlso length > 0 AndAlso Me.sb(0) = ControlChars.Lf Then
                i = 1
                num = 1
                Me.bLastCarriageReturn = False
            End If
            While i < length
                Dim c As Char = Me.sb(i)
                If c = ControlChars.Cr OrElse c = ControlChars.Lf Then
                    If c = ControlChars.Cr AndAlso i + 1 < length AndAlso Me.sb(i + 1) = ControlChars.Lf Then
                        i += 1
                    End If

                    Dim obj As String = Me.sb.ToString(num, i + 1 - num)

                    num = i + 1

                    SyncLock Me.messageQueue
                        Me.messageQueue.Enqueue(obj)
                    End SyncLock
                End If
                i += 1
            End While

            ' Flush Fix: Send Whatever is left in the buffer
            Dim endOfBuffer As String = Me.sb.ToString(num, length - num)
            SyncLock Me.messageQueue
                Me.messageQueue.Enqueue(endOfBuffer)
                num = length
            End SyncLock
            ' End Flush Fix

            If Me.sb(length - 1) = ControlChars.Cr Then
                Me.bLastCarriageReturn = True
            End If
            If num < length Then
                Me.sb.Remove(0, num)
            Else
                Me.sb.Length = 0
            End If
            Me.FlushMessageQueue()
        End Sub
        Private Sub FlushMessageQueue()
            While Me.messageQueue.Count > 0
                SyncLock Me.messageQueue
                    If Me.messageQueue.Count > 0 Then
                        Dim data As String = DirectCast(Me.messageQueue.Dequeue(), String)
                        If Not Me.cancelOperation Then
                            Me.userCallBack(data)
                        End If
                    End If
                    Continue While
                End SyncLock
                Exit While
            End While
        End Sub
        Friend Sub WaitUtilEOF()
            If Me.eofEvent IsNot Nothing Then
                Me.eofEvent.WaitOne()
                Me.eofEvent.Close()
                Me.eofEvent = Nothing
            End If
        End Sub
    End Class

    Public Class DataReceivedEventArgs
        Inherits EventArgs
        Friend _data As String
        ''' <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
        ''' <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
        ''' <filterpriority>2</filterpriority>
        Public ReadOnly Property Data() As String
            Get
                Return Me._data
            End Get
        End Property
        Friend Sub New(data As String)
            Me._data = data
        End Sub
    End Class
End Namespace

エラー1〜3は警告のようで、実際に機能する可能性があります。特にエラー4と5は、「Public Event OutputDataRecieved(sender As Object、e As DataRecievedEventArgs)はイベントであり、直接呼び出すことはできません。RaiseEventステートメントを使用して発生します。イベント。"

イベントハンドラーは、私が試したどのコードコンバーターでも機能しないようで、手動で変換するためのVBスキルが不足しています。

このクラスを実際に機能するように適切に変換できるフレンドリーな魂はいますか?

どうもありがとう!

ローマ人

4

4 に答える 4

4

ソリューションで、新しいc#プロジェクトを追加します。このc#コードをその中に配置します。

vbプロジェクトから、c#プロジェクトへの参照を追加します。

これで、vbからc#オブジェクトを呼び出すことができます。

ILに変換しても同じです。

于 2012-09-12T13:36:29.677 に答える
2

BeginErrorReadLineメソッドのシグネチャにOverloadsキーワードを追加する必要があります。

 Public Overloads Sub BeginErrorReadLine()   '<-------------Error 3

イベント宣言は、基本クラスのイベント宣言と競合するため、シャドウとして宣言する必要があります。

 Public Shadows Event OutputDataReceived As DataReceivedEventHandler '<----------Error 1

次に、FixedOutputReadNotifyUserメソッドで、C#の場合のようにイベントハンドラーをチェックして、イベントハンドラーが何もないかどうかを確認する必要はありません。VBがあなたに代わってそれを行います。代わりに、次のように単純に上げます。

Friend Sub FixedOutputReadNotifyUser(data As String)
    Dim dataReceivedEventArgs As New DataReceivedEventArgs(data)
    RaiseEvent OutputDataReceived(Me, dataReceivedEventArgs)
End Sub

最後の問題は、元のクラスで大文字と小文字の区別を使用して、「cancelOperation」フィールドと「CancelOperation」メソッドを区別していることです。最良のオプションは、次のようにフィールドの前にアンダースコアを付けることPrivate _CancelOperation As Booleanです。次に、クラス内の対応する参照を修正します。

于 2012-09-12T13:53:34.557 に答える
0

「エラー4」と「エラー5」の場合は、代わりにこれを使用してください。ローカル変数を「イベント」で終わる非表示のVBバッキングデリゲートフィールドに設定する必要があることに注意してください。また、イベントが何もないかどうかをチェックしていないので、ローカル変数が何もないというテストはまだ有効ですが、デリゲートタイプのローカル変数です。「エラー5」のアプローチはまったく同じです。

Friend Sub FixedOutputReadNotifyUser(ByVal data As String)
    Dim outputDataReceived As DataReceivedEventHandler = Me.OutputDataReceivedEvent
    If outputDataReceived IsNot Nothing Then
        Dim dataReceivedEventArgs As New DataReceivedEventArgs(data)
        If Me.SynchronizingObject IsNot Nothing AndAlso Me.SynchronizingObject.InvokeRequired Then
            Me.SynchronizingObject.Invoke(outputDataReceived, New Object() { Me, dataReceivedEventArgs })
            Return
        End If
        outputDataReceived(Me, dataReceivedEventArgs)
    End If
End Sub
于 2012-09-12T16:35:24.930 に答える
0

以下は私が現在使用しているコードです。プロジェクトに2番目の名前空間を含める方法がわからなかったため、名前空間を削除し、コードを新しいモジュールに貼り付けました。次に、元のc#ソリューションで提案されているように、「pasnewprocess」を「pasnewFixedProcess」に変更しました。

すべての提案を再度ありがとう!

あなたたち最高!

私がやろうとしていることの全体像を示すために、フォームコードも含めています。私は自分自身をプログラマーとは考えていませんので、ほとんどの人ができるほど洗練されていない場合は、ご容赦ください。これは、plinkを使用してSSHセッションをリモート制御し、Ciscoルータでコマンドを自動的に実行することを目的としています。

コードは完全に機能し、1つ(うまくいけば)小さな欠陥が残っています。基になるplink.exeを閉じる場合は、入力ストリームと出力ストリームも閉じたいと思います。これまでのところ、「借りた」クラスでそれを行う方法を見つけることができませんでした。

フォームのクローズイベントでやりたいと思います。plink.exeプロセスを強制終了しますが、別のセッションでフォームを再度開くと、出力が2倍になり、もう一度閉じて再度開くと、出力が3倍になります...

ストリームを適切に閉じる方法について何か提案はありますか?

Imports System
Imports System.Text
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports System.ComponentModel
Imports Microsoft.VisualBasic

Imports System.Collections.Generic
Imports System.Linq


Imports System.Collections



Module Module2


    Friend Delegate Sub UserCallBack(ByVal data As String)
    Public Delegate Sub DataReceivedEventHandler(ByVal sender As Object, ByVal e As DataReceivedEventArgs)




    Public Class FixedProcess
        Inherits Process
        Friend output As AsyncStreamReader
        Friend [error] As AsyncStreamReader
        Public Shadows Event OutputDataReceived As DataReceivedEventHandler
        Public Shadows Event ErrorDataReceived As DataReceivedEventHandler

        Public CancelAll As Boolean = False

        Public Overloads Sub BeginOutputReadLine()
            Dim baseStream As Stream = StandardOutput.BaseStream
            Me.output = New AsyncStreamReader(Me, baseStream, New UserCallBack(AddressOf Me.FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding)
            Me.output.BeginReadLine()
        End Sub

        Public Overloads Sub BeginErrorReadLine()
            Dim baseStream As Stream = StandardError.BaseStream
            Me.[error] = New AsyncStreamReader(Me, baseStream, New UserCallBack(AddressOf Me.FixedErrorReadNotifyUser), StandardError.CurrentEncoding)
            Me.[error].BeginReadLine()
        End Sub

        Friend Sub FixedOutputReadNotifyUser(ByVal data As String)
            Dim dataReceivedEventArgs As New DataReceivedEventArgs(data)
            RaiseEvent OutputDataReceived(Me, dataReceivedEventArgs)

        End Sub





        Friend Sub FixedErrorReadNotifyUser(ByVal data As String)
            Dim errorDataReceivedEventArgs As New DataReceivedEventArgs(data)
            RaiseEvent ErrorDataReceived(Me, errorDataReceivedEventArgs)

        End Sub




    End Class

    Friend Class AsyncStreamReader
        Implements IDisposable
        Friend Const DefaultBufferSize As Integer = 1024
        Private Const MinBufferSize As Integer = 128
        Private stream As Stream
        Private encoding As Encoding
        Private decoder As Decoder
        Private byteBuffer As Byte()
        Private charBuffer As Char()
        Private _maxCharsPerBuffer As Integer
        Private process As Process
        Private userCallBack As UserCallBack
        Public cancelOperation As Boolean
        Private eofEvent As ManualResetEvent
        Private messageQueue As Queue
        Private sb As StringBuilder
        Private bLastCarriageReturn As Boolean
        Public Overridable ReadOnly Property CurrentEncoding() As Encoding
            Get
                Return Me.encoding
            End Get
        End Property
        Public Overridable ReadOnly Property BaseStream() As Stream
            Get
                Return Me.stream
            End Get
        End Property
        Friend Sub New(ByVal process As Process, ByVal stream As Stream, ByVal callback As UserCallBack, ByVal encoding As Encoding)
            Me.New(process, stream, callback, encoding, 1024)
        End Sub
        Friend Sub New(ByVal process As Process, ByVal stream As Stream, ByVal callback As UserCallBack, ByVal encoding As Encoding, ByVal bufferSize As Integer)
            Me.Init(process, stream, callback, encoding, bufferSize)
            Me.messageQueue = New Queue()
        End Sub
        Private Sub Init(ByVal process As Process, ByVal stream As Stream, ByVal callback As UserCallBack, ByVal encoding As Encoding, ByVal bufferSize As Integer)
            Me.process = process
            Me.stream = stream
            Me.encoding = encoding
            Me.userCallBack = callback
            Me.decoder = encoding.GetDecoder()
            If bufferSize < 128 Then
                bufferSize = 128
            End If
            Me.byteBuffer = New Byte(bufferSize - 1) {}
            Me._maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize)
            Me.charBuffer = New Char(Me._maxCharsPerBuffer - 1) {}
            Me.cancelOperation = False
            Me.eofEvent = New ManualResetEvent(False)
            Me.sb = Nothing
            Me.bLastCarriageReturn = False
        End Sub
        Public Overridable Sub Close()
            Me.Dispose(True)
        End Sub
        Private Sub IDisposable_Dispose() Implements IDisposable.Dispose
            Me.Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If disposing AndAlso Me.stream IsNot Nothing Then
                Me.stream.Close()
            End If
            If Me.stream IsNot Nothing Then
                Me.stream = Nothing
                Me.encoding = Nothing
                Me.decoder = Nothing
                Me.byteBuffer = Nothing
                Me.charBuffer = Nothing
            End If
            If Me.eofEvent IsNot Nothing Then
                Me.eofEvent.Close()
                Me.eofEvent = Nothing
            End If
        End Sub
        Friend Sub BeginReadLine()
            If Me.cancelOperation Then
                Me.cancelOperation = False
            End If
            If Me.sb Is Nothing Then
                Me.sb = New StringBuilder(1024)
                Me.stream.BeginRead(Me.byteBuffer, 0, Me.byteBuffer.Length, New AsyncCallback(AddressOf Me.ReadBuffer), Nothing)
                Return
            End If
            Me.FlushMessageQueue()
        End Sub
        Friend Sub _CancelOperation()
            Me.cancelOperation = True
        End Sub
        Private Sub ReadBuffer(ByVal ar As IAsyncResult)

            Dim num As Integer

            Try
                num = Me.stream.EndRead(ar)
            Catch generatedExceptionName As IOException
                num = 0
            Catch generatedExceptionName As OperationCanceledException
                num = 0
            End Try
            If num = 0 Then
                SyncLock Me.messageQueue
                    If Me.sb.Length <> 0 Then
                        Me.messageQueue.Enqueue(Me.sb.ToString())
                        Me.sb.Length = 0
                    End If
                    Me.messageQueue.Enqueue(Nothing)
                End SyncLock
                Try
                    Me.FlushMessageQueue()
                    Return
                Finally
                    Me.eofEvent.[Set]()
                End Try
            End If
            Dim chars As Integer = Me.decoder.GetChars(Me.byteBuffer, 0, num, Me.charBuffer, 0)
            Me.sb.Append(Me.charBuffer, 0, chars)
            Me.GetLinesFromStringBuilder()
            Me.stream.BeginRead(Me.byteBuffer, 0, Me.byteBuffer.Length, New AsyncCallback(AddressOf Me.ReadBuffer), Nothing)


        End Sub
        Private Sub GetLinesFromStringBuilder()
            Dim i As Integer = 0
            Dim num As Integer = 0
            Dim length As Integer = Me.sb.Length
            If Me.bLastCarriageReturn AndAlso length > 0 AndAlso Me.sb(0) = ControlChars.Lf Then
                i = 1
                num = 1
                Me.bLastCarriageReturn = False
            End If
            While i < length
                Dim c As Char = Me.sb(i)
                If c = ControlChars.Cr OrElse c = ControlChars.Lf Then
                    If c = ControlChars.Cr AndAlso i + 1 < length AndAlso Me.sb(i + 1) = ControlChars.Lf Then
                        i += 1
                    End If

                    Dim obj As String = Me.sb.ToString(num, i + 1 - num)

                    num = i + 1

                    SyncLock Me.messageQueue
                        Me.messageQueue.Enqueue(obj)
                    End SyncLock
                End If
                i += 1
            End While

            ' Flush Fix: Send Whatever is left in the buffer
            Dim endOfBuffer As String = Me.sb.ToString(num, length - num)
            SyncLock Me.messageQueue
                Me.messageQueue.Enqueue(endOfBuffer)
                num = length
            End SyncLock
            ' End Flush Fix

            If Me.sb(length - 1) = ControlChars.Cr Then
                Me.bLastCarriageReturn = True
            End If
            If num < length Then
                Me.sb.Remove(0, num)
            Else
                Me.sb.Length = 0
            End If
            Me.FlushMessageQueue()
        End Sub
        Private Sub FlushMessageQueue()
            While Me.messageQueue.Count > 0
                SyncLock Me.messageQueue
                    If Me.messageQueue.Count > 0 Then
                        Dim data As String = DirectCast(Me.messageQueue.Dequeue(), String)
                        If Not Me.cancelOperation Then
                            Me.userCallBack(data)
                        End If
                    End If
                    Continue While
                End SyncLock
                Exit While
            End While
        End Sub
        Friend Sub WaitUtilEOF()
            If Me.eofEvent IsNot Nothing Then
                Me.eofEvent.WaitOne()
                Me.eofEvent.Close()
                Me.eofEvent = Nothing
            End If
        End Sub
    End Class

    Public Class DataReceivedEventArgs
        Inherits EventArgs
        Friend _data As String
        ''' <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
        ''' <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
        ''' <filterpriority>2</filterpriority>
        Public ReadOnly Property Data() As String
            Get
                Return Me._data
            End Get
        End Property
        Friend Sub New(ByVal data As String)
            Me._data = data
        End Sub
    End Class






End Module

と私のフォームコード...

Imports System
Imports System.Text
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports System.ComponentModel
Imports Microsoft.VisualBasic

Imports System.Collections.Generic
Imports System.Linq


Imports System.Collections




Public Class Form3

    ' Define static variables shared by class methods.
    Private Shared shellOutput As StringBuilder = Nothing
    Private Shared numOutputLines As Integer = 0
    Private Shared stdIN As StreamWriter
    Private Shared p As New FixedProcess 'as new
    Private Shared oldOutlineData As String = ""
    Private Shared PasswordInput As Boolean = False



    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        ShowISDNStatus()

    End Sub

    Public Sub ShowISDNStatus()
        Dim p_info As New ProcessStartInfo 'as new
        p_info.FileName = Form1.PlinkPath
        p_info.Arguments = Form1.KommandoArguments
        p_info.UseShellExecute = False
        p_info.CreateNoWindow = True
        p_info.RedirectStandardOutput = True
        p_info.RedirectStandardInput = True
        p_info.RedirectStandardError = True
        ' Set our event handler to asynchronously read the shell output.
        AddHandler p.OutputDataReceived, AddressOf dirOutputHandler
        AddHandler p.ErrorDataReceived, AddressOf dirOutputHandler



        shellOutput = New StringBuilder
        p.StartInfo = p_info
        p.Start()
        p.BeginOutputReadLine()
        p.BeginErrorReadLine()
        stdIN = p.StandardInput

        'stdIN.WriteLine("enable" & vbCr & "K#limdor1" & vbCrLf)
        'Timer1.Enabled = True
        'System.Threading.Thread.Sleep(500)

        'stdIN.WriteLine("term len 0")
        'stdIN.WriteLine("show isdn status")

        stdIN.WriteLine("enable" & vbCr & Form1.TextPassword.Text & vbCrLf)
        Timer1.Enabled = True
        System.Threading.Thread.Sleep(500)
        Me.TextBox2.Text = ""
        stdIN.WriteLine("term len 0")
        stdIN.WriteLine("show isdn status")
        Me.TextBox1.Select(TextBox1.Text.Length, 0)
        Me.TextBox1.ScrollToCaret()

    End Sub

    Private Shared Sub dirOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
        ''If Not String.IsNullOrEmpty(outLine.Data) Then
        shellOutput.Append(outLine.Data)

        'For i = 1 To Len(outLine.Data)
        '    FormDebug.TextBox1.Text = "Len von OutlineData: " & Len(outLine.Data) & " " & Asc(Mid(outLine.Data, i, 1)) & "---" & Mid(outLine.Data, i, 1)
        'Next

        If outLine.Data = "Store key in cache? (y/n) " Then
            stdIN.WriteLine("y")
        End If

        Form3.TextBox1.Text = outLine.Data

        ''End If
    End Sub

    Private Sub Form3_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load



    End Sub

    Private Sub Form3_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing


        p.Kill()



    End Sub


    Private Sub TextBox2_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles TextBox2.PreviewKeyDown

        If e.KeyCode = Keys.Return Then

            If PasswordInput = False Then
                If Me.TextBox2.Text = "en" Then
                    Me.TextBox2.UseSystemPasswordChar = True
                    Me.TextBox2.Text = ""
                    PasswordInput = True
                    Timer1.Enabled = False
                    Me.TextBox1.AppendText("Password:")

                ElseIf Me.TextBox2.Text = "ena" Then
                    Me.TextBox2.UseSystemPasswordChar = True
                    Me.TextBox2.Text = ""
                    PasswordInput = True
                    Timer1.Enabled = False
                    Me.TextBox1.AppendText("Password:")

                ElseIf Me.TextBox2.Text = "enab" Then
                    Me.TextBox2.UseSystemPasswordChar = True
                    Me.TextBox2.Text = ""
                    PasswordInput = True
                    Timer1.Enabled = False
                    Me.TextBox1.AppendText("Password:")

                ElseIf Me.TextBox2.Text = "enabl" Then
                    Me.TextBox2.UseSystemPasswordChar = True
                    Me.TextBox2.Text = ""
                    PasswordInput = True
                    Timer1.Enabled = False
                    Me.TextBox1.AppendText("Password:")

                ElseIf Me.TextBox2.Text = "enable" Then
                    Me.TextBox2.UseSystemPasswordChar = True
                    Me.TextBox2.Text = ""
                    PasswordInput = True
                    Timer1.Enabled = False
                    Me.TextBox1.AppendText("Password:")

                ElseIf Me.TextBox2.Text = "" Then
                    stdIN.WriteLine()
                    System.Threading.Thread.Sleep(500)
                    Me.TextBox1.Select(TextBox1.Text.Length, 0)
                    Me.TextBox1.ScrollToCaret()
                Else
                    stdIN.WriteLine(Me.TextBox2.Text)
                    System.Threading.Thread.Sleep(500)
                    Me.TextBox2.Text = ""
                    Me.TextBox1.Text = shellOutput.ToString
                    Me.TextBox1.Select(TextBox1.Text.Length, 0)
                    Me.TextBox1.ScrollToCaret()
                End If

            Else

                stdIN.WriteLine("enable" & vbCr & Me.TextBox2.Text & vbCrLf)
                System.Threading.Thread.Sleep(500)
                Me.TextBox2.Text = ""
                Timer1.Enabled = True
                Me.TextBox2.UseSystemPasswordChar = False
                stdIN.WriteLine("term len 0")
                Me.TextBox1.Select(TextBox1.Text.Length, 0)
                Me.TextBox1.ScrollToCaret()
                PasswordInput = False

            End If


        End If

    End Sub


    Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged

    End Sub

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        Me.TextBox1.SelectAll()
        Me.TextBox1.ScrollToCaret()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        ' If Me.TextBox1.Text <> shellOutput.ToString Then Me.TextBox1.Text = shellOutput.ToString
        Me.TextBox1.Text = shellOutput.ToString

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        FormDebug.Show()
        'Dim frm As New Form3
        'Static Num As Integer

        'Num = Num + 1
        'frm.Text = "Copy of Form3 - " & Num
        'frm.Show()
    End Sub
End Class
于 2012-09-13T09:50:05.617 に答える