C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

DOSを実行→戻り値を取得、テキストボックスに出力したい。

[トピック内 18 記事 (1 - 18 表示)]  << 0 >>

■82989 / inTopicNo.1)  DOSを実行→戻り値を取得、テキストボックスに出力したい。
  
□投稿者/ Using FFmpeg (1回)-(2017/02/24(Fri) 18:33:07)

分類:[VB.NET/VB2005 以降] 

VB.NET , visual studio 2015 で FFmpeg を利用した音声変換プログラムを作成中です。

タイトルの通り、Dos コマンドを実行し、戻り値(実行結果)を取得し、マルチラインのテキストボックスに出力し、ユーザーに進行状況を知らせることができるようにしたいのですが、
直接VB.NETからDOSに指示を入力する、という方法を知り、やってみたところ、エラー、思った通りの結果にならない等で無理かな・・・と思い、
バッチファイルを作成、実行という手段をとってみたのですが、戻り値をテキストボックスに出力する方法がわからず、質問させていただきました。

よろしくお願いいたします。

(初めての質問です。)
引用返信 編集キー/
■82990 / inTopicNo.2)  Re[1]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Hongliang (503回)-(2017/02/24(Fri) 18:44:32)
・今時のWindowsではDOSは使われていません。コマンドプロンプトで、コンソールアプリケーションを実行します。他のプロセスの子プロセスとしてコンソールアプリケーションを動かすなら、コマンドプロンプトを非表示にもできます。
・プログラムの戻り値というのは、通常はプログラムが終了時に返してくる整数値を指します。これを取得したところで進行状況をどうこうすることはできないでしょう。

ffmpegの場合、(引数にもよるけど)経過を標準エラー出力に出していくので、それを受け取って解析することになるでしょう。
Processクラスを中心にまずお調べになって、色々試してみて下さい。
引用返信 編集キー/
■82991 / inTopicNo.3)  Re[2]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (2回)-(2017/02/24(Fri) 19:04:20)
2017/02/24(Fri) 19:06:19 編集(投稿者)

No82990 (Hongliang さん) に返信
> ・今時のWindowsではDOSは使われていません。コマンドプロンプトで、コンソールアプリケーションを実行します。他のプロセスの子プロセスとしてコンソールアプリケーションを動かすなら、コマンドプロンプトを非表示にもできます。

>>すいません。コマンドプロンプトのことです。
>>非表示は知っているのですが、出力等が取得できません・・・。

> ・プログラムの戻り値というのは、通常はプログラムが終了時に返してくる整数値を指します。これを取得したところで進行状況をどうこうすることはできないでしょう。

>>間違いが多くてすいません。
>>実行結果のことです。

> ffmpegの場合、(引数にもよるけど)経過を標準エラー出力に出していくので、それを受け取って解析することになるでしょう。

>>なるほど・・・難しそうですね・・・。(あまり深くわかっていない)汗
> Processクラスを中心にまずお調べになって、色々試してみて下さい。

>>結構いろいろ調べたりくふうしてみたのですが、わかりません。
>>(助けてーー…)

引用返信 編集キー/
■82993 / inTopicNo.4)  Re[3]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ 魔界の仮面弁士 (1148回)-(2017/02/24(Fri) 21:21:58)
行頭「>」は引用記号なので、自分の発言の前ではなく
相手の発言の前に付与してください。


No82991 (Using FFmpeg さん) に返信
> 非表示は知っているのですが、出力等が取得できません・・・。
> 実行結果のことです。

標準出力を取得するには、Process クラスの StandardOutput プロパティで受け取ります。
http://dobon.net/vb/dotnet/process/standardoutput.html



> すいません。コマンドプロンプトのことです。

少し前の Windows だと、コマンド プロンプトと DOS プロンプトの
両方が使えたりもしましたが、現行バージョンの Windows では command.com が無くなり
コマンド プロンプト(と PowerShell)だけになりましたね。

Windows 95 や 98 あたりまで遡ると、「MS-DOS モード(Windows を終了して MS-DOS で起動)」と
「MS-DOS プロンプト ウィンドウ(ウィンドウ表示)」と「MS-DOS プロンプト(全画面表示)」の
3 種があったりして、特に NEC 版 Windows ではt(以下本題と無関係なので自粛
引用返信 編集キー/
■82994 / inTopicNo.5)  Re[4]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (4回)-(2017/02/24(Fri) 21:59:04)
No82993 (魔界の仮面弁士 さん) に返信
> 行頭「>」は引用記号なので、自分の発言の前ではなく
> 相手の発言の前に付与してください。

あー、そうだったんですか。わかりました!
>
> ■No82991 (Using FFmpeg さん) に返信
>>非表示は知っているのですが、出力等が取得できません・・・。
>>実行結果のことです。
>
> 標準出力を取得するには、Process クラスの StandardOutput プロパティで受け取ります。
> http://dobon.net/vb/dotnet/process/standardoutput.html

回答ありがとうございます。
上記のサイトはもうすでに行ったことがあり、「出力とエラーの両方を読み取る」というところをやったのですが、
OutputDataReceived・ErrorDataReceived イベントハンドラで「値がNULLで、NULLを参照することはできない」等の主旨のエラーがでてしまうんですよね・・・
それでバッチファイル作戦でやろうと思ったのですが、結構難しくて…

DOSのことも興味深く、面白かったです。(´▽`)アリガト!
引用返信 編集キー/
■82995 / inTopicNo.6)  Re[5]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Azulean (781回)-(2017/02/25(Sat) 08:17:35)
No82994 (Using FFmpeg さん) に返信
> 上記のサイトはもうすでに行ったことがあり、「出力とエラーの両方を読み取る」というところをやったのですが、
> OutputDataReceived・ErrorDataReceived イベントハンドラで「値がNULLで、NULLを参照することはできない」等の主旨のエラーがでてしまうんですよね・・・

そのエラーが出たときのコードも書いた方が良いと思いますよ。
でないと、先に進みませんので…。
引用返信 編集キー/
■82997 / inTopicNo.7)  Re[6]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (5回)-(2017/02/25(Sat) 15:28:47)
2017/02/25(Sat) 15:45:32 編集(投稿者)
2017/02/25(Sat) 15:43:56 編集(投稿者)
2017/02/25(Sat) 15:30:14 編集(投稿者)

> そのエラーが出たときのコードも書いた方が良いと思いますよ。
> でないと、先に進みませんので…。
回答ありがとうございます。
そうします。長いコードなのですが、貼ってみたいと思います。
要らない部分も多いのかな・・・とおもいながら、
わからないので貼っておきます。
デザインのほうはあったほうが良ければ言ってください。(ソースコードあればなんとなくわかるかな・・・?)

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Imports System.IO
Imports System.Drawing.Color
Imports System.Text.Encoding

Public Class Form1
Dim UserName As String = Environment.UserName
Dim FileLength As Byte = 0 'For Concat
Dim sw As New Stopwatch()

Private Sub Form1_load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Output.Text = ("C:\Users\" & UserName & "\Desktop\Output.mp3")
End Sub
Private Sub TextBox7_DragDrop(sender As Object, e As DragEventArgs) Handles TextBox7.DragDrop
FileLength = FileLength + 1
Dim FileName = DirectCast(e.Data.GetData(DataFormats.FileDrop), String())(0)
TextBox7.AppendText(" -i" + " " + Chr(34) + FileName + Chr(34))
End Sub

Private Sub TextBox7_DragEnter(sender As Object, e As DragEventArgs) Handles TextBox7.DragEnter
If (e.Data.GetDataPresent(DataFormats.FileDrop)) = True Then
e.Effect = DragDropEffects.All
Else
e.Effect = DragDropEffects.None
End If
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim EncodeYN As DialogResult =
MessageBox.Show("Are you sure to encode now??", "Check", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
If EncodeYN = DialogResult.OK Then
'=========================================
Dim test As String = 0
Dim text As String = TextBox7.Text

'====================================================================================2017/02/09

'Concat or not
If (Button2.Text = "ON") Then
TextBox8.Text = ("ffmpeg" & text & " -filter_complex " & Chr(34) & "concat=n=" & FileLength & ":v=0:a=1" & Chr(34))
Else
TextBox8.Text = ("ffmpeg" & text)
End If

'Channel
If (Channel.Value <> 0) Then
TextBox8.Text = (TextBox8.Text & " -ac " & Channel.Value)
End If

'BitRate
If (BitRate.Text <> String.Empty) Then
TextBox8.Text = (TextBox8.Text & " -ab " & BitRate.Text)
End If

'Sampling
If (Sampling.Text <> String.Empty) Then
TextBox8.Text = (TextBox8.Text & " -ar " & Sampling.Text)
End If

'Volume
Select Case (Volume.Text)
Case String.Empty, "256", "0"
'Do nothing
Case Else
TextBox8.Text = (TextBox8.Text & " -vol " & Volume.Text)
End Select

TextBox8.Text = (TextBox8.Text & Chr(32) & Output.Text & "\" & OutputName.Text)
'================================================================================END

'-------Same OutPutName Check---------
If File.Exists(text) Then
MessageBox.Show("File name is already exists , Please type another name")
Return
End If

'============== dobon.net ここから ================
      Dim p As New System.Diagnostics.Process()

'出力とエラーをストリームに書き込むようにする
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
'OutputDataReceivedとErrorDataReceivedイベントハンドラを追加
AddHandler p.OutputDataReceived, AddressOf p_OutputDataReceived
AddHandler p.ErrorDataReceived, AddressOf p_ErrorDataReceived

p.StartInfo.FileName = _
System.Environment.GetEnvironmentVariable("ComSpec")
p.StartInfo.RedirectStandardInput = False
p.StartInfo.CreateNoWindow = True
p.StartInfo.Arguments = textbox8.text

'起動
p.Start()

'非同期で出力とエラーの読み取りを開始
p.BeginOutputReadLine()
p.BeginErrorReadLine()

p.WaitForExit()
p.Close()

Console.ReadLine()
End Sub

ElseIf EncodeYN = DialogResult.Cancel Then

End If

End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If (Button2.BackColor = White) Then
Button2.Text = "ON"
Button2.BackColor = CornflowerBlue
Button2.ForeColor = White
ElseIf (Button2.BackColor = CornflowerBlue) Then
Button2.Text = "OFF"
Button2.BackColor = White
Button2.ForeColor = Black
Else
MessageBox.Show("Something wrong with inside the program...")
End If
End Sub

Private Sub Change_Click(sender As Object, e As EventArgs) Handles Change.Click
'Create Instance (folder browser dialog)
Dim fbd As New FolderBrowserDialog
'Description
fbd.Description = "Set Output Folder..."
'root folder (Default : desktop)
fbd.RootFolder = Environment.SpecialFolder.Desktop
'First Directory , need under the root folder
fbd.SelectedPath = Environment.SpecialFolder.Desktop
'Can make new folder (Default : true)
fbd.ShowNewFolderButton = True
'Show Dialog
If fbd.ShowDialog(Me) = DialogResult.OK Then
Output.Text = fbd.SelectedPath
End If

End Sub

Private Sub AboutMe_Click(sender As Object, e As EventArgs) Handles AboutMe.Click
MessageBox.Show("Created By XXXX , XXXX", "(c) XXXX", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
End Class

'OutputDataReceivedイベントハンドラ
'行が出力されるたびに呼び出される
Private Shared Sub p_OutputDataReceived(sender As Object, _
e As System.Diagnostics.DataReceivedEventArgs)
'出力された文字列を表示する
textbox1.appendtext(e.Data)
End Sub

'ErrorDataReceivedイベントハンドラ
Private Shared Sub p_ErrorDataReceived(sender As Object, _
e As System.Diagnostics.DataReceivedEventArgs)
'エラー出力された文字列を表示する
textbox1.appendtext("ERR>{0}", e.Data)
End Sub
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
こんな感じです。
</pre></pre>
引用返信 編集キー/
■83000 / inTopicNo.8)  Re[7]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (6回)-(2017/02/25(Sat) 17:46:35)
あと、エラーは
OutputDataReceived と
ErrorDataReceived イベントハンドラで、どうやら e.DataがNullらしく、

System.NullReferenceException というエラーになってしまいます。
引用返信 編集キー/
■83005 / inTopicNo.9)  Re[8]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Azulean (782回)-(2017/02/25(Sat) 20:13:36)
No83000 (Using FFmpeg さん) に返信
> OutputDataReceived と
> ErrorDataReceived イベントハンドラで、どうやら e.DataがNullらしく、
>
> System.NullReferenceException というエラーになってしまいます。

e.Data は Nothing(null) で終了するようなので、String.IsNullOrEmpty で事前にチェックしてください。
引用返信 編集キー/
■83007 / inTopicNo.10)  Re[9]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (7回)-(2017/02/25(Sat) 22:35:49)
No83005 (Azulean さん) に返信
> ■No83000 (Using FFmpeg さん) に返信
>>OutputDataReceived と
>>ErrorDataReceived イベントハンドラで、どうやら e.DataがNullらしく、
>>
>>System.NullReferenceException というエラーになってしまいます。
>
> e.Data は Nothing(null) で終了するようなので、String.IsNullOrEmpty で事前にチェックしてください。

というのは、
Private Shared Sub p_OutputDataReceived(sender As Object, e As System.Diagnostics.DataReceivedEventArgs)
If (e.Data <> String.Empty) Then
  textbox1.appendtext(e.Data)
ElseIf (e.Data = String.Empty Then

End If
End Sub

こういうことですよね・・?

これでも同じエラーになるんですよね・・・
何故か・・。


引用返信 編集キー/
■83008 / inTopicNo.11)  Re[10]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Hongliang (504回)-(2017/02/25(Sat) 22:59:57)
String.EmptyとNothingは別物です。
String.IsNullOrEmptyを提示されているのになぜ<> String.Emptyという方法をとるのでしょうか…?

なお、e.DataにNothing(null)がどういう状況で送信されるのかも、その際にどうすべきかも、
https://msdn.microsoft.com/ja-jp/library/system.diagnostics.datareceivedeventhandler(v=vs.100).aspx
MSDNのDataReceivedEventHandlerのページにサンプル付きで書かれてたりします。
引用返信 編集キー/
■83009 / inTopicNo.12)  Re[11]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (8回)-(2017/02/26(Sun) 08:56:07)
No83008 (Hongliang さん) に返信
> String.EmptyとNothingは別物です。
> String.IsNullOrEmptyを提示されているのになぜ<> String.Emptyという方法をとるのでしょうか…?
そうなんですか!知らなかったです。
ただ、String.EmptyをNothingに置き換えても同じエラーが出ます。(なんか勘違いしてるのかな…僕)

> なお、e.DataにNothing(null)がどういう状況で送信されるのかも、その際にどうすべきかも、
> https://msdn.microsoft.com/ja-jp/library/system.diagnostics.datareceivedeventhandler(v=vs.100).aspx
> MSDNのDataReceivedEventHandlerのページにサンプル付きで書かれてたりします。

ありがとうございます。
後で読んでみます。
引用返信 編集キー/
■83010 / inTopicNo.13)  Re[8]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Azulean (783回)-(2017/02/26(Sun) 09:27:43)
ところで。

No83000 (Using FFmpeg さん) に返信
> イベントハンドラで、どうやら e.DataがNullらしく、
> System.NullReferenceException というエラーになってしまいます。

「e.Data が Nothing(null) らしく」は事実ですか?推測ですか?

改めて見ると、イベントハンドラに Shared ついています。
Shared が指定された textbox1 変数は存在していますか? 適切な TextBox の参照を代入していますか?


No82997 (Using FFmpeg さん) に返信
> 'ErrorDataReceivedイベントハンドラ
> Private Shared Sub p_ErrorDataReceived(sender As Object, _
> e As System.Diagnostics.DataReceivedEventArgs)
> 'エラー出力された文字列を表示する
> textbox1.appendtext("ERR>{0}", e.Data)
> End Sub

AppendText は String を 1 個だけ指定可能なはずなので、このコードはコンパイルエラーとなります。
どういう状況ですか?
コンパイルエラーに気づかずに過去のビルド結果を実行していませんか?
引用返信 編集キー/
■83011 / inTopicNo.14)  Re[12]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (9回)-(2017/02/26(Sun) 09:46:16)
ビルドしてみました。

MSDNを参考に↓の様にしました。
 
  Private Shared Sub p_OuputDataReceived(sender As Object, e As DataReceivedEventArgs)
If Not String.IsNullOrEmpty(e.Data) Then
Form1.TextBox1.AppendText(e.Data)
End If
End Sub

Private Shared Sub p_ErrorDataReceived(sender As Object, e As DataReceivedEventArgs)
If Not String.IsNullOrEmpty(e.Data) Then
Form1.TextBox1.AppendText("ERR>{0}")
Form1.TextBox1.AppendText(e.Data)
End If
End Sub

すごい!エラーは出なくなりました。
ただ、実行結果がTextBox1に表示されません・・・。
TextBox1側の設定とかはあるのでしょうか・・・?

引用返信 編集キー/
■83012 / inTopicNo.15)  Re[9]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (10回)-(2017/02/26(Sun) 10:15:01)
No83010 (Azulean さん) に返信
> ところで。
>
> ■No83000 (Using FFmpeg さん) に返信
>>イベントハンドラで、どうやら e.DataがNullらしく、
>>System.NullReferenceException というエラーになってしまいます。
>
> 「e.Data が Nothing(null) らしく」は事実ですか?推測ですか?
https://msdn.microsoft.com/ja-jp/library/sxw2ez55.aspx を見て、Nullだと思ったのですが、推測になるんですかね・・・?

>
> 改めて見ると、イベントハンドラに Shared ついています。
> Shared が指定された textbox1 変数は存在していますか? 適切な TextBox の参照を代入していますか?
>
打ち間違えました。すいません。System.NullReferenceException のエラーが出たときは Form1.TextBox1.AppendText(e.Data) にしていました。
>
> ■No82997 (Using FFmpeg さん) に返信
>> 'ErrorDataReceivedイベントハンドラ
>> Private Shared Sub p_ErrorDataReceived(sender As Object, _
>> e As System.Diagnostics.DataReceivedEventArgs)
>> 'エラー出力された文字列を表示する
>> textbox1.appendtext("ERR>{0}", e.Data)
>> End Sub
>
> AppendText は String を 1 個だけ指定可能なはずなので、このコードはコンパイルエラーとなります。
あ・・w
Form1.TextBox1.AppendText("ERR>{0}")
Form1.TextBox1.AppendText(e.Data)
の間違いです。(アホですいませんw)
> どういう状況ですか?
> コンパイルエラーに気づかずに過去のビルド結果を実行していませんか?
引用返信 編集キー/
■83013 / inTopicNo.16)  Re[13]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Azulean (784回)-(2017/02/26(Sun) 10:32:07)
No83011 (Using FFmpeg さん) に返信
> ただ、実行結果がTextBox1に表示されません・・・。
> TextBox1側の設定とかはあるのでしょうか・・・?

単に何も出力がこないだけ…ということはないですかね?
AppendText のところにブレークポイントを設定して、きちんとデータが来ているか確認してください。


きちんとデータが来ているのであれば、VB.NET 特有の暗黙のインスタンスによる問題でしょうね。
そもそも、イベントハンドラを Shared にする必要あるのですか?
必要がないなら Shared を外して、Form1.TextBox1.AppendText ではなく、単に TextBox1.AppendText とした方がかんたんでしょう。

もし、それで InvalidOperationException が出るなら Invoke などを調べてください。
引用返信 編集キー/
■83036 / inTopicNo.17)  Re[10]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (12回)-(2017/02/28(Tue) 20:11:29)
ちょっと忙しくなってきたので、1週間以内ぐらいにやってみたいと思います。
引用返信 編集キー/
■83173 / inTopicNo.18)  Re[11]: DOSを実行→戻り値を取得、テキストボックスに出力したい。
□投稿者/ Using FFmpeg (13回)-(2017/03/09(Thu) 15:10:25)
コマンドプロンプトの画面を表示しても問題なくなったので、BAT作成+実行作戦にします。
回答本当にありがとうございました。
勉強になりました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ