- PR -

コマンドプロンプトで実行ファイル実行中 C#

投稿者投稿内容
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-05-12 12:11
引用:

artさんの書き込み (2005-05-12 11:46) より:

コード:
mp.StartInfo.FileName = "MORE.COM"; 
mp.StartInfo.UseShellExecute = false; 
mp.StartInfo.RedirectStandardInput = true; 
mp.StartInfo.RedirectStandardOutput = true; 
mp.StartInfo.CreateNoWindow = false; 
mp.Start(); 
mp.StandardInput.WriteLine("test aaa");
mp.StandardInput.Close();
String s = mp.StandardOutput.ReadToEnd();
Console.WriteLine("abcc", s);
String t = mp.StandardOutput.ReadToEnd();
Console.WriteLine("abcc", t);
result = mp.StandardOutput.ReadToEnd();





太字にしたところですが、Console.WriteLineの数あるオーバーロードのうち、先頭の引数にStringを用いた場合、その文字列は書式指定文字列になるってことは分かっていますか?
この書式ではsやtに何か文字列が入っても握りつぶされるだけになってしまいます。

またReadToEndは文字通りストリームの最後まで読み取るメソッドです。
標準出力ストリームは、そのプロセスが出力する全ての文字が終了するまでEOFを吐きません。
このコードではsへの代入部分でmore.comの出力が全て(改行を含めて)読み取られてしまいます。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-12 13:44
Hongliangさん、ご返信ありがとうございます。

> 太字にしたところですが、Console.WriteLineの数あるオーバーロードのうち、先頭の引数にStringを用いた場合、その文字列は書式指定文字列になるってことは分かっていますか?
> この書式ではsやtに何か文字列が入っても握りつぶされるだけになってしまいます。
すいません、寝ぼけてたみたいで・・・初歩的なミスでしたね。

> またReadToEndは文字通りストリームの最後まで読み取るメソッドです。
> 標準出力ストリームは、そのプロセスが出力する全ての文字が終了するまでEOFを吐きません。
> このコードではsへの代入部分でmore.comの出力が全て(改行を含めて)読み取られてしまいます。
なるほど、そうでしたか。ご指摘ありがとうございます。
ですが、これを差し引いても、入力させるのはやはり上手くいかないみたいで・・・
お知恵を拝借できたらと思います。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-12 14:54
すいません、質問追記です。

この場合の「入力」に限らず、
他のexeファイルをプロセスとして実行して、そのexeから何か、入力でも何でも求められた場合に、
それに対して何かを返すということはできますでしょうか?

宜しくお願い致します。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-05-12 14:57
こんにちは。

もしかして、微妙に勘違いされているのでは?
>mp.StartInfo.FileName = "MORE.COM";
この部分、このまま記述されてます?
MORE.COMは標準入出力のテストの例を示すだけに使われているものなので、ここにartさんが入力を受け取って出力を返す実行モジュールを指定するのですが。

「そんなことわかってるよん」てことであれば、私の勘違いなので申し訳ないっす。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-12 15:16
noderaさん、ご返信ありがとうございます。

そんなことわかってるよんって言いたいですが、残念ながら言えません・・・
その部分、そのまま記述しています。
もしよろしければ、サンプルを少しでもお見せしていただけると嬉しいのですが。

一応現在は、
mp.StartInfo.FileName = "test.exe";
#test.exe直で「入力」に入力させる
mp.StartInfo.FileName = "CMD.EXE";
#CMD.EXE経由でtest.exeの「入力」に入力させる
mp.StartInfo.FileName = "MORE.COM";
#MORE.COM経由でtest.exeの「入力」に入力させる
の3通り考えているのですが、どれか一つでも目的が果たせればと思っている次第です。

宜しくお願い致します。
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2005-05-12 15:19
どもでし。がると申します。
んっと…ものすごく基本的な部分で引っかかってるように思われたので、
少しだけ。
引用:

コマンドプロンプトを起動してこれを実行させれば、
入力1・入力2はそれぞれキーボードで入力できますよね。
これをC#でプロセスとしてコマンドプロンプトを立ち上げ、
同様に実行させていきたいのですが、
入力1・2を入力させるところで引っかかってしまいます。


なのですが。
プログラムをざっくりと拝見した限りですと、stdin(Winだと
「標準入力ストリーム」でいいのかな?)に対して特になにも
細工をしていないように拝見されます。
まず、コンソールとプログラムの関係をきちんと把握されるとよいか
と思います。

artさんがやりたいことは、
プログラムAから、プログラムB(以降複数あり)を別プロセスで動かして
入力を受け取る、という仕様のようですが。
Dosプロンプトで直接動かしているプログラムがAである以上、コマンド画面
からの入力は、当然のようにプログラムAのstdinに入り込みます。
ですので、プログラムBやCにそのstdinをまわしたい場合、プログラムAが
意図的にその辺を処理してあげる必要があります。
で。
動かすプログラムが1本なら、自分のstdoutと子プロセスのstdinをつなげる
とかって大技もあるのですが。
複数のプログラムであれば、手前のプログラムAできちんとその辺は
コーディングする必要があると思うです。

なにかの参考にでもなれば幸いです。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-12 17:24
がるがるさん、ご返信ありがとうございます。

この議題のそのものは自分の中では解決していないのですが、
結局勘違いから、この議題の方法でないとできないと思ってしまっていて・・・
やりたかったことは無事解決致しました。

ご返信くださった皆様、ありがとうございました。
自分の甘さを痛感した故、もう一度、一から勉強していこうと思います。
またご厄介になることもあると思いますが、その時は宜しく御願い致します。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-05-12 18:53
こんにちは。

別の方法で解決されたようなので、もう必要ないかもしれませんが、情報としてサンプル載せておきます。

まず、標準入力を受け取って、結果を返すコンソールアプリ(ConsoleApplication1.exe)
コード:
[STAThread]
static void Main(string[] args)
{
	string read1 = Console.ReadLine();
	string read2 = Console.ReadLine();
	string write = string.Empty;
	try
	{
		int i1 = int.Parse(read1);
		int i2 = int.Parse(read2);
		write = string.Format("{0}", i1 + i2);
	}
	catch(Exception e)
	{
		write = e.ToString();
	}
	Console.WriteLine(write);
}


2度入力を受け取り、intに変換し入力値を足した結果を、出力とします。
例)
3 ・・・ 入力1
5 ・・・ 入力2
8 ・・・ 出力

で、これを呼び出す側。適当なWindowsアプリケーションです。画面にボタン(button1)がありクリックしたときのイベントに記述したとします。
コード:
private void button1_Click(object sender, System.EventArgs e)
{

	Process mp = new Process();
	mp.StartInfo.FileName = "ConsoleApplication1.exe"; 
	mp.StartInfo.UseShellExecute = false; 
	mp.StartInfo.RedirectStandardInput = true; 
	mp.StartInfo.RedirectStandardOutput = true; 
	mp.StartInfo.CreateNoWindow = true;
	mp.Start(); 

*1	mp.StandardInput.WriteLine("3");
*2	mp.StandardInput.WriteLine("5");
	mp.StandardInput.Close();

*3	String s = mp.StandardOutput.ReadToEnd();
	mp.WaitForExit();
	MessageBox.Show(s);

}


*1と*2の部分でコンソールアプリへ入力、*3がコンソールアプリからの結果を受け取る部分です。
(結果はメッセージボックスで表示としました。メッセージボックスには8が表示される)

質問の件は上記のようなことがやりたかったのだと受け止めましたがどうだったでしょうか?
(あ、返答は別になくてもかまいませんが)

スキルアップ/キャリアアップ(JOB@IT)