VB .NETからWSLを起動しLinuxコマンドを実行するサンプル

土曜日 , 16, 2月 2019 Leave a comment

VB .NETからWSL(Windows Subsystem for Linux)を起動しLinuxコマンドを実行、標準出力に出力された内容を.NET側で受け取りコンソールに出力するサンプルプログラムです。

サンプルプログラムはLinuxのPSコマンドを実行し、標準出力の内容を逐次読み込むパターンとイベントハンドラを用いて非同期に読み込むパターンの2つを用意しました。

BackgroundWorkerなどと組み合わせると長時間実行するLinuxコマンドから出力される内容を.NET側で受け取りGUIに進行状況を表示しながら実行することもできます。

  1. Linuxコマンドから標準出力に出力出力された内容を逐次読み込むサンプル

' This software is distributed under the license of NYSL.
' ( http://www.kmonos.net/nysl/ )

''' 
''' <summary>
''' WSL上でLinuxコマンドを実行し、標準出力に出力された内容をコンソールへ出力
''' </summary>
Public Shared Sub InvokeWslCommand()

    Dim psi As New ProcessStartInfo()

    ' WSLのディストリビューション(ubuntu、ubuntu1804など)
    psi.FileName = "ubuntu1804"
    ' WSL上で実行するコマンド(実行したい部分をダブルクオーテーションで囲む)
    psi.Arguments = "run ""ps -aux"""

    ' リダイレクト設定(標準出力のみをリダイレクト)
    psi.RedirectStandardInput = False
    psi.RedirectStandardOutput = True
    psi.RedirectStandardError = False

    ' シェル使用せず、ウィンドウ表示なし
    psi.UseShellExecute = False
    psi.CreateNoWindow = True

    ' WSLプロセスを起動
    Using p = Process.Start(psi)

        ' 標準出力に出力される内容を読み取り
        Dim reader = p.StandardOutput
        Do Until reader.EndOfStream
            Dim line = reader.ReadLine
            Console.WriteLine(line)
        Loop

        ' プロセスの終了待ち
        p.WaitForExit()

	' 終了コードを出力
        Console.WriteLine("exit-code=" & p.ExitCode)

    End Using

End Sub
  1. Linuxコマンドから標準出力に出力された内容をイベントで受け取り非同期で読み込むサンプル

' This software is distributed under the license of NYSL.
' ( http://www.kmonos.net/nysl/ )

''' 

''' <summary>
''' WSL上でLinuxコマンドを実行し、標準出力に出力された内容をコンソールへ出力(非同期版)
''' </summary>
Public Shared InvokeWslCommandAsync()

    Dim psi As New ProcessStartInfo()

    ' WSLのディストリビューション(ubuntu、ubuntu1804など)
    psi.FileName = "ubuntu1804"
    ' WSL上で実行するコマンド(実行したい部分をダブルクオーテーションで囲む)
    psi.Arguments = "run ""ps -aux"""

    ' リダイレクト設定(標準出力のみをリダイレクト)
    psi.RedirectStandardInput = False
    psi.RedirectStandardOutput = True
    psi.RedirectStandardError = False

    ' シェル使用せず、ウィンドウ表示なし
    psi.UseShellExecute = False
    psi.CreateNoWindow = True

    ' WSLプロセスを起動
    Using p = Process.Start(psi)

        ' 出力を受け取った時のハンドラを設定
        AddHandler p.OutputDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                                Console.WriteLine(e.Data)
                                            End Sub

        ' 非同期読み込み開始
        p.BeginOutputReadLine()

        ' プロセスの終了待ち
        p.WaitForExit()

        ' 非同期読み込みをキャンセル
        p.CancelOutputRead()

	' 終了コードを出力
        Console.WriteLine("exit-code=" & p.ExitCode)

    End Using


End Sub