2008-08-29 67 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);行立即返回,因爲它應該,但批處理文件似乎掛起,而不執行。有任何想法嗎?

編輯:見我的回答如下的批處理文件的內容。

  • output.txt永遠不會被創建。

我添加這些行:

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

,並通過他們在調試模式下階梯。代碼掛在ReadLine()上。我很難過!

+0

你可以發佈你的批處理文件的代碼,並且你是否嘗試從你的批處理文件發出回聲,以便你可以看到它正在啓動? – 2008-08-29 08:40:03

回答

5

我相信我找到了答案。看來微軟,在所有他們無限的智慧,已經從在Windows Server 2003布蘭登·湯普金斯通過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 =真的嗎?

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

爲了「看」到底發生了什麼,我建議你將過程轉換爲更具交互性的東西(關閉Echo)並放置一些「打印件」以查看是否有任何事情正在發生。運行後,output.txt文件中的內容是什麼?

是否bmail實際執行?

在之前/之前放置一些照片以查看發生了什麼。

同時添加「@」的論點,以防萬一:

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

它是很簡單的東西:)

0

我想CMD.EXE掛起如果參數不正確。

如果該批處理正確執行,那麼我會shell執行它,而不是。

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); 
      } 
     } 
    } 
}