VB.NET: Visual Basic から curl コマンドを使う方法

プログラムから Webページ上の情報にアクセスするケースは多々あります。
こういう時に使うのが、Unixの場合は、wget や curl コマンド。FreeBSDの場合は、これらがデフォルトでは入っていないため、あとから pkg コマンドで入れる必要があります。

HTTPプロトコルを使うときの、wget と curl の大きな違いは、

wget : サーバーのレスポンスをファイルに保存する

curl : サーバーのレスポンスを標準入力に出力する

だと思います。そのほか、細かいオプションの指定方法に違いはありますけど、戻ってくる値をファイルに保存して、後から同じデータに何度もアクセスしたりサーバーへのアクセスを減らしたい場合は wget を、レスポンスをメモリ上で処理したい場合は、curl コマンドの方が便利だと思います。curl は予定しているサイズよりもレスポンスが巨大だったら、メモリをバカ食いしたりプログラムが落ちるかもしれませんので、レスポンス内容があらかじめわかっている場合だけ使うのが安全です。curl コマンドは、httpやftp以外のプロトコルも扱えるので、機能面では curl の方が優れているのかも。

私は Unix 上では wget の方を多用していますが、残念ながらWindows10でも wget は標準ではない。しかし、なぜか curl は標準で入ってます。ラッキー! なので、Visual Basicでは、curl.exe を使うことにします。

C:\Windows\System32>curl.exe -help
Usage: curl [options...] 
 -d, --data           HTTP POST data
 -f, --fail                 Fail fast with no output on HTTP errors
 -h, --help       Get help for commands
 -i, --include              Include protocol response headers in the output
 -o, --output         Write to file instead of stdout
 -O, --remote-name          Write output to a file named as the remote file
 -s, --silent               Silent mode
 -T, --upload-file    Transfer local FILE to destination
 -u, --user  Server user and password
 -A, --user-agent     Send User-Agent  to server
 -v, --verbose              Make the operation more talkative
 -V, --version              Show version number and quit

This is not the full help, this menu is stripped into categories.
Use "--help category" to get an overview of all categories.
For all options use the manual or "--help all".

curl.exe が標準で入っているとはいえ Visual Basic から使うには、vb.netに含まれていないコマンドをアクセスするための準備が必要になります。で、web検索してみました。

見つかったページの一つ。

https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/149procstart/procstart.html」に書かれている、サンプルを参考に、以下のように書いてみました。Visual Basic Console プロジェクトのデフォルトで作られるスケルトン部分を赤字の部分だけ編集すると、下のプログラムからメモ帳が開きました。

Imports System.Diagnostics

Module Program
    Sub Main(args As String())
        Process.Start("notepad.exe")
    End Sub
End Module

system.diagnostics.process.start を使えば、外部コマンドを起動できるってことです。

問題はこの後。
実際に使いたいのはGUIアプリではなく、コマンドライン。notepad.exe を curl.exe に置き換えてみました。

ハンドルされていない例外

ハンドルされていない例外、System.ComponentModel.Win32Exception:指定したファイルが見つかりません。

となってしまいます。curl.exe、これは system32 の下にあるから、フルパス指定する必要ないはずなんだけどな~と思いながら、フルパス指定しても同じ結果に。ということは、根本的に書式が間違ってる。

もっと調べればこのコマンドでも解決策が見つかるのかもしれませんが、次の検索結果の方法「https://dobon.net/vb/dotnet/process/standardoutput.html」に頼ることにします。

こちらも、system.diagnostics.process.start ですが、結構、curl.exeをコールするまでの儀式が長い。サンプルの表示領域が広いので、ここでは短くするために、コメント行を削除させてもらいます。コメント行が重要なので、コメントに関しては上記URLを参照のこと。

Imports System.Diagnostics

Module Program
    Sub Main(args As String())
        Dim p As New System.Diagnostics.Process()

        p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec")
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardOutput = True
        p.StartInfo.RedirectStandardInput = False
        p.StartInfo.CreateNoWindow = True
        p.StartInfo.Arguments = "/c curl.exe -help"

        p.Start()

        Dim results As String = p.StandardOutput.ReadToEnd()

        p.WaitForExit()
        p.Close()

        Console.WriteLine(results)
    End Sub
End Module

サンプルプログラムでは、(/c はそのままで)dir c:\ /w となっているところを、”curl.exe -help” と書き換えると、DOS窓が開いて出力が表示されました。コマンド出力結果は変数 results の中身なので、プログラム中からresultsをアクセスすることで必要な情報にアクセスできることがわかります。

dobon.net さん、ありがとうございます。

ここまでわかれば、あとは、-help の部分を、いろいろなコマンドオプションと置き換えれば、好きなサイトをアクセスして、サイト情報をプログラムで処理できるってことになります。

コメントを残す