初期の問題
この問題が提起され、他の場所で対処されている場合は、お詫び申し上げます。私はこのサイトとGoogle全体を検索しましたが、運がありませんでした。
ユーザーが非常に単純なGUI(ファイルを選択するための「参照」ボタン、修飾子を選択するためのチェックボックス、および出力用のテキストボックス)。
問題は、プロセスから標準出力またはエラーを読み取ろうとするたびに、すぐに停止し、何も出力されないことです。「createnowindow」を False に設定し、出力またはエラーをリダイレクトしないことで、プロセス引数が正しいことを確認しました。
プロセスが実際に実行されているかどうかを確認するために、proc.start の後に "while" ループを挿入します。
Do While proc.HasExited = False
textbox.AppendText(i & vbNewLine)
i += 1
Loop
プロセスが正常に実行されている場合、カウントは約 80 または 90 まで取得されます。標準出力または標準エラーで何かを行うと、テキスト ボックスには初期値の「0」しか表示されません。「何でも」とは、をproc.StandardOutput.ReadToEnd
変数に代入することを意味します。を使用するとproc.StandardOutput.Peek
a が返さ-1
れ、ループは 0 のままです。
出力またはエラーのいずれかのみをリダイレクトし (両方ではない)、プロセスが新しいウィンドウを開くことができるようにすると、新しいウィンドウは空になり、すぐに終了することに気付きました(リダイレクトされたものを読み取ろうとしていない場合でも)どちらもリダイレクトされない場合は、数ページの結果が表示されてから終了します。これが正常なのか、ファイル比較実行可能ファイルが何らかの方法で出力ストリームとエラー ストリームを混合して出力を生成しているのか、あるいはそのようなことが可能なのかどうかはわかりません。
私は一般的にコーディングに非常に慣れていないため (VB.net で約 1 か月間作業しており、それが私のプログラミング経験の範囲です)、私のトラブルシューティングと仮定が完全にベースから外れている可能性があることを認識しています。 、そして誰でも提供できる支援に感謝します。現状では、私は完全に困惑しており、経験が浅いために代替案を探すのが難しくなっています (たとえば、非同期出力を正しく処理する方法がわかりません)。参考までに、現在の私の恥ずかしいほど不格好なコードを次に示します。
Dim cmdinput As String = """" & file1path & """" & " " & """" & file2path & """"
Dim cmdmods As String = " "
Dim i As Integer = 0
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = "C:\Windows\System32\fc.exe"
proc.StartInfo.Arguments = cmdinput & cmdmods
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.RedirectStandardError = True
proc.Start()
proc.StandardOutput.ReadToEnd()
Do While proc.HasExited = False
scanbox.AppendText(i & vbNewLine)
i += 1
Loop
考えられる解決策
Hans Passant がエラーが表示されるはずだと指摘した後、他に何もないとしても、コードをいじって結果を得ることができましたが、最適とは言えませんでした。FC.exe を直接実行する代わりに、CMD.exe を実行しました。以前にこれを試してみましたが、うまくいきませんでしたが、それは CMD.exe が "fc" を process.startinfo.arguments として受け入れないためです。
「fc」をproc.standardinput.writeline()でcmd.exeに渡しました。この時点で、CMD.exe のリダイレクトされた出力を読み取ることができました。FC.exe を直接読み取れない理由はまだわかりませんが、当面の応急処置としてはこれで十分です。他の誰かが完全に優れたコマンドライン実行可能ファイルに GUI を追加する必要性を感じ、問題が発生した場合に備えて、ここに私のコードを示します。
Public Sub compare()
Dim cmdinput As String = "fc " & """" & file1path & """" & " " & """" & file2path & """"
Dim cmdmods As String = " "
Dim proc As New Process
proc.StartInfo.CreateNoWindow = True
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = "C:\Windows\System32\cmd.exe"
proc.StartInfo.Arguments = cmdinput & cmdmods
proc.StartInfo.RedirectStandardOutput = True
proc.StartInfo.RedirectStandardError = True
proc.StartInfo.RedirectStandardInput = True
proc.Start()
proc.StandardInput.WriteLine(cmdinput)
proc.StandardInput.Close()
scanbox.AppendText(proc.StandardOutput.ReadToEnd)
proc.WaitForExit()
proc.Close()
proc.Dispose()
End Sub
Hans Passant と Dan Verdolino が私のとりとめのない質問に提案を提供してくれたことに大変感謝しています。私はこれを行う方法をまとめようとして、1週間壁に頭をぶつけてきました。