2008-08-29 7 views
12

私は、Webアプリケーションから別のユーザーとしてバッチファイルを実行しようとしています。何らかの理由で、バッチファイルがハングアップします。私は "cmd.exe"がタスクマネージャーで実行されているのを見ることができますが、永遠にそこに座っていて、殺すことができず、バッチファイルは実行されていません。ここに私のコードがあります:あなたが推測していなかった場合はC#.Net:なぜ私のProcess.Start()がぶら下がっていますか?

SecureString password = new SecureString(); 
foreach (char c in "mypassword".ToCharArray()) 
    password.AppendChar(c); 

ProcessStartInfo psi = new ProcessStartInfo(); 
psi.WorkingDirectory = @"c:\build"; 
psi.FileName = Environment.SystemDirectory + @"\cmd.exe"; 
psi.Arguments = "/q /c build.cmd"; 
psi.UseShellExecute = false; 
psi.UserName = "builder"; 
psi.Password = password; 
Process.Start(psi); 

、このバッチファイルは、自分のアプリケーション(このコマンドを実行しているものとは異なるアプリケーション)を構築します。

Process.Start(psi);行はただちに戻りますが、バッチファイルは実行せずにハングアップしているようです。何か案は?

EDIT:バッチファイルの内容については、私の答えを参照してください。

  • output.txtは決して作成されません。

私はこれらの行を追加:

psi.RedirectStandardOutput = true; 
Process p = Process.Start(psi); 
String outp = p.StandardOutput.ReadLine(); 

をし、デバッグモードでそれらを介して辞任しました。コードはReadLine()にあります。私は困惑している!

+0

バッチファイルのコードを投稿し、バッチファイルからエコーを発信して、起動していることを確認できましたか? –

答えて

5

私は答えを見つけたと信じています。 Microsoft、すべての彼らの無限の知恵では、Windows Server 2003 BrendenトンプキンスにIISによって実行されているからバッチファイルをブロックしているようだここでは回避策があります。私のために動作しません

http://codebetter.com/blogs/brendan.tompkins/archive/2004/05/13/13484.aspx

私のバッチファイルはIFとGOTOを使用しているので、単純なバッチファイルではうまく動作します。

0

私の推測では、build.cmdが何らかのユーザーのやりとりや返信を待っていると思います。最後の "> logfile.txt"演算子を使用してコマンドの出力をログに記録すると、問題の発見に役立つ場合があります。

2

build.cmdを見ることなく、何が起こっているのかを知るのは難しいですが、Path.Combine(arg1、arg2);を使ってパスを構築する必要があります。パスを構築する正しい方法です。

Path.Combine(Environment.SystemDirectory, "cmd.exe"); 

私は覚えていませんが、UseShellExecute = trueを設定する必要はありませんか?

1

「デバッグ」それはstandardoutputを使用し、それから読み取ることがあるのもう一つの可能​​性:ここで

psi.RedirectStandardOutput = True; 
Process proc = Process.Start(psi); 
String whatever = proc.StandardOutput.ReadLine(); 
0

がbuild.cmdの内容です:

@echo off 
set path=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;%path% 

msbuild myproject.csproj /t:Build > output.txt 
IF NOT ERRORLEVEL 1 goto :end 

:error 
bmail -s k2smtpout.secureserver.net -f [email protected] -t [email protected] -a "Build failed." -m output.txt -h 

:end 
del output.txt 

あなたが見ることができるように、私は」何も出力しないように注意してください。それは、ビルドが失敗した場合に私に電子メールで送られるファイルにすべて行きます。私は実際にこのファイルを夜間に予定された作業としてかなり長い間実行してきました。私はそれを要求に応じて実行できるWebアプリケーションを構築しようとしています。

これまでのおかげでよろしく! Path.Combineのヒントは特に役に立ちました。

1

何が起こっているのかを見るためには、プロセスをよりインタラクティブなものに変えて(エコーをオフにして)、実際に何か起こっているかどうかを確認することをおすすめします。これを実行した後、output.txtファイルには何が入っていますか?

実際にはbmailは実行されますか?

何が起きているのかを確認するには、その前/後にプリントを入れます。

も追加し、「@」の引数に、念のために:

psi.Arguments = @"/q /c build.cmd"; 

それは非常に単純なものである必要があります:)

0

私はパラメータが正しくない場合cmd.exeのがハングアップだと思います。

バッチが正しく実行されたら、代わりにこのようにシェルを実行するだけです。

ProcessStartInfo psi = new ProcessStartInfo(); 
Process p = new Process(); 
psi.WindowStyle = ProcessWindowStyle.Hidden; 
psi.WorkingDirectory = @"c:\build"; 
psi.FileName = @"C:\build\build.cmd"; 
psi.UseShellExecute = true; 
psi.UserName = "builder"; 
psi.Password = password; 
p.StartInfo = psi; 
p.Start(); 

また、cmd.exeでbuild.cmdが見つからない場合もありますが、ファイルの絶対パスを指定しないのはなぜですか?

0

あなたのエンドラインは何ですか?コードがReadLineでハングアップすると、バッチファイルを読み取ることができないという問題が発生する可能性があります。

3

バッチファイルではなくC#ですべての作業を行うのはなぜですか?

私は退屈していたので、私はこの本当の素早さを書きました。コマンドラインの切り替えやファイルパスがわからないので、どのように行うのかの概要です。

using System; 
using System.IO; 
using System.Text; 
using System.Security; 
using System.Diagnostics; 

namespace asdf 
{ 
    class StackoverflowQuestion 
    { 
     private const string MSBUILD = @"path\to\msbuild.exe"; 
     private const string BMAIL = @"path\to\bmail.exe"; 
     private const string WORKING_DIR = @"path\to\working_directory"; 

     private string stdout; 
     private Process p; 

     public void DoWork() 
     { 
      // build project 
      StartProcess(MSBUILD, "myproject.csproj /t:Build", true); 
     } 

     public void StartProcess(string file, string args, bool redirectStdout) 
     { 
      SecureString password = new SecureString(); 
      foreach (char c in "mypassword".ToCharArray()) 
       password.AppendChar(c); 

      ProcessStartInfo psi = new ProcessStartInfo(); 
      p = new Process(); 
      psi.WindowStyle = ProcessWindowStyle.Hidden; 
      psi.WorkingDirectory = WORKING_DIR; 
      psi.FileName = file; 
      psi.UseShellExecute = false; 
      psi.RedirectStandardOutput = redirectStdout; 
      psi.UserName = "builder"; 
      psi.Password = password; 
      p.StartInfo = psi; 
      p.EnableRaisingEvents = true; 
      p.Exited += new EventHandler(p_Exited); 
      p.Start(); 

      if (redirectStdout) 
      { 
       stdout = p.StandardOutput.ReadToEnd(); 
      } 
     } 

     void p_Exited(object sender, EventArgs e) 
     { 
      if (p.ExitCode != 0) 
      { 
       // failed 
       StringBuilder args = new StringBuilder(); 
       args.Append("-s k2smtpout.secureserver.net "); 
       args.Append("-f [email protected] "); 
       args.Append("-t [email protected] "); 
       args.Append("-a \"Build failed.\" "); 
       args.AppendFormat("-m {0} -h", stdout); 

       // send email 
       StartProcess(BMAIL, args.ToString(), false); 
      } 
     } 
    } 
} 
関連する問題