2008-08-29 70 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); 
      } 
     } 
    } 
}