- PR -

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

投稿者投稿内容
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-10 15:09
お初に質問させていただきます。
Visual C#プロジェクト ASP.NET Webアプリケーションを作ろうとしているのですが。

例えばまず、言語問わず実行ファイル(test.exe)があるとします。
実行ファイルの内容は、コマンドプロンプトで実行させると、
「入力1」「入力2」の入力をそれぞれ求めてきて、
それぞれ入力し終えると、「入力1」「入力2」が出力されるものとします。

コマンドプロンプトを起動して、それを実行させると、
___________________________
C:\aaa\bbb>test.exe
入力1:(キーボードで何か入力する)
入力2:(キーボードで何か入力する)
実行結果:「(入力1に入力した内容)」「(入力2に入力した内容)」
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
このような流れになるとした場合についてお尋ねします。

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


Process mp = new Process();
mp.StartInfo.FileName = "CMD.EXE";
mp.StartInfo.UseShellExecute = false;
mp.StartInfo.RedirectStandardInput = true;
mp.StartInfo.RedirectStandardOutput = true;
mp.StartInfo.CreateNoWindow = false;
mp.StartInfo.WorkingDirectory = @"C:\aaa\bbb";
mp.Start();
this.StartThread();

public void StartThread()
{
System.Threading.ThreadStart readThread = new System.Threading.ThreadStart (ReadThread);
System.Threading.ThreadStart writeThread = new System.Threading.ThreadStart (WriteThread);
System.Threading.Thread rThread = new System.Threading.Thread (readThread);
System.Threading.Thread wThread = new System.Threading.Thread (writeThread);
rThread.Name = "ReadThread";
wThread.Name = "WriteThread";
rThread.Start ();
wThread.Start ();
wThread.Join();
rThread.Join();
}

string result;

private void ReadThread()
{
result = mp.StandardOutput.ReadToEnd();
}

private void WriteThread()
{
mp.StandardInput.WriteLine("test.exe");
mp.StandardInput.WriteLine("text");
mp.StandardInput.WriteLine("text");
mp.StandardInput.WriteLine("exit");
}


このような感じになっているのですが、これだと、
各入力に対しては何も入力されず、コマンド命令としてしか入力されません。

入力1・入力2に入力させる方法を何かアドバイスしていただけたら幸いです。
宜しく御願い致します。
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2005-05-10 16:44
cmd.exe 経由で test.exe を実行しているのはなぜでしょうか?
直接 test.exe のプロセスを作れば上手くいきそうな気がします。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-10 17:14
>k-nakさん
早速のご返信ありがとうございます。

test.exeとは別の、ある実行ファイルを実際には実行させたいのですが、
直接それでプロセスを作ろうとして上手くいかなかったため、
コマンドプロンプトでやったほうが良いのかと思った次第です。
上書きしてしまったため、cmd.exe経由じゃないほうの失敗したやつは残っていませんが・・・
実際にはcmd.exe経由でなくとも、稼動すれば問題はありません。
その実行ファイルも実行内容的にはtest.exeとほぼ同様なのですが、
入力のさせ方を、また、ユーザを指定してプロセスを開始する方法も、
併せてご教授いただけたら幸いです。
宜しくお願い致します。
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-11 17:33
コマンドプロンプト経由でなくても、test.exeをプロセスとして直で実行させる場合でもよいので、
入力1・2に入力させる方法の、些細なアドバイスだけでも、宜しくお願い致します。
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2005-05-11 19:53
以下のコードを試してみましたが、問題なく動きました。

コード:
Process mp = new Process();
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 message.");
mp.StandardInput.Close();

String s = mp.StandardOutput.ReadToEnd();
Console.WriteLine("{0}", s);



ただ、コンソールアプリとして動かした時の話なので、ASP.NETだと話が違ってくるのかな?(サービス用のユーザで動くわけだし)


>ユーザを指定してプロセスを開始する方法

Processクラス周りのヘルプを見てみましたがなさそうですね。
Win32APIですとCreateProcessAsUserを使うところなのですが。
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2005-05-11 20:26
> 以下のコードを試してみましたが、問題なく動きました。

単純な入出力ならそれで可能でしょうけど、少しでも凝ったことを
やろうとするとデッドロックが発生します。

http://dobon.net/vb/dotnet/process/standardoutput.html
http://ukamen.hp.infoseek.co.jp/Programming1/Process/
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2005-05-12 00:09
>todoさん
補足ありがとうございます。

デッドロックの件はヘルプにも載ってたので気づいてはいたんですけど、さすがに手抜き過ぎましたね^^;
# 前記のコードもWriteLine⇒Flushを2行分続けてやればはまりそうな予感……


>artさん
とりあえずProcessクラスを使う箇所を抜き出して、まずはコンソールアプリでターゲットのEXEを正しく呼び出せることを確認してみてはどうでしょうか?

それでもし問題ないとなると、ASP.NET内で動くときのユーザー(IISを動かしているユーザー?)が標準入出力と対話する権限がない、ってことなんだと思います。
# 一時的にWebサーバのユーザーを一般ユーザに変更してみて、
# それで正常動作したら原因確定ですね。

もし、ユーザ権限関係が原因だとするとGoogleで
「ASP ユーザ 偽装」
で検索した結果が参考になる……かな?

たとえばこれなど。

http://www.athomejp.com/goldfish/vcs/usercamouflage.asp
「あるユーザーになりすます」
art
常連さん
会議室デビュー日: 2005/05/10
投稿数: 25
投稿日時: 2005-05-12 11:46
k-nakさん、todoさん、ご返信ありがとうございます。

コード:
						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();





k-nakさんのを参考に、こんな感じで動かしてみたのですが、
実行はされているようですが、上手く動作していないようでした。
あいかわらず入力のところで詰まってしまっています。
(おそらく入力そのものがされていません)

more.comというのは初めて見たので、少し調べてみたところ、
「出力を一度に1画面ずつ表示。」と説明が書いてあったのですが、
これは入力・あるいはexeの実行もできるのでしょうか?

>> ユーザを指定してプロセスを開始する方法
> Processクラス周りのヘルプを見てみましたがなさそうですね。
> Win32APIですとCreateProcessAsUserを使うところなのですが。
自分でも調べてみて、やはりなさそうでしたので、
過去ログ等を拝見し、現在は実行ユーザである「ASPNET」の所属グループを「Administrators」に変更するなど、いろいろ権限を与えてためしています。
なので、実行する上ではとりあえずユーザ権限に関しては問題ありません。
#かなり危険そうですが・・・

>とりあえずProcessクラスを使う箇所を抜き出して、まずはコンソールアプリでターゲットのEXEを正しく呼び出せることを確認してみてはどうでしょうか?
本来は「test -a」のようにオプションをつけると「入力」を求められるもので、
オプションなしであれば、「入力」に関係しない処理を施します。
最初の例でいうと、オプションをつけなければ、「入力1」「入力2」は求められず、
「実行結果:」のみが出力されるといった感じです。
オプションなしで実行した場合は、正しく処理されていたので、
その入力のところだけがネックだと思っているのですが・・・

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