C# Process.Start cmd.exe赢得';t运行在IIS中运行时作为agument传递的cmd文件

C# Process.Start cmd.exe赢得';t运行在IIS中运行时作为agument传递的cmd文件,c#,batch-file,cmd,process.start,C#,Batch File,Cmd,Process.start,我整个上午都在搜索和试验这个,我被难住了。我在IIS中运行了一个aspx页面,并调用以下c#函数。我试图让它运行一个cmd文件并返回cmd文件的输出。我在下面的代码中尝试了五种不同的选项: protected String RunMyCmdFileAndGetResponse() { Process proc = new Process (); proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe"; // proc.S

我整个上午都在搜索和试验这个,我被难住了。我在IIS中运行了一个aspx页面,并调用以下c#函数。我试图让它运行一个cmd文件并返回cmd文件的输出。我在下面的代码中尝试了五种不同的选项:

protected String RunMyCmdFileAndGetResponse() {
    Process proc = new Process ();
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe";
//  proc.StartInfo.Arguments = @"/c echo hello";                    <== 1
//  proc.StartInfo.Arguments = @"/c c:\mypath\myfile_badname.cmd";  <== 2
//  proc.StartInfo.Arguments = @"/c type c:\mypath\myfile.cmd";     <== 3
    proc.StartInfo.Arguments = @"/c c:\mypath\myfile.cmd";      //  <== 4
//  proc.StartInfo.Arguments = @"/c call c:\mypath\myfile.cmd";     <== 5
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.CreateNoWindow = true;

    proc.Start();
    string response = proc.StandardOutput.ReadToEnd();
    response += proc.StandardError.ReadToEnd();
    proc.WaitForExit();
    return response;
}
手动运行时,此cmd文件按预期工作,生成myfilelog.txt并返回测试行2。使用c代码执行时:

  • 选项1起作用-按预期返回“hello”响应
  • 选项2按预期失败,表明myfile_badname.cmd未被识别为有效命令
  • 选项3按预期工作-它返回myfile.cmd的内容作为响应-这确认我能够找到并读取该文件
  • 选项4不起作用——据我所知,它应该起作用。它不会挂起,但也不会返回任何响应,也不会执行cmd文件(不生成myfilelog.txt)
  • 选项5-结果与选项4相同
注意-我还尝试修改myfile.cmd以删除第1行(创建日志文件),而只保留第2行以回显响应。以防创建日志文件时出现权限问题。同样的结果

任何帮助都将不胜感激

更新以添加解决方案:

来自@MaxOvrdrv的答案让我有了不同的想法。在运行进程时确实存在某种限制。在IIS上下文中使用UseShellExecute=false启动-如果主参数是可执行文件(cmd文件、脚本文件等),它将不会运行它。我尝试将SomeExample.cmd传递给cmd.exe,将SomeExample.js传递给cscript.exe

然而。。。我能够用一种间接的方式来欺骗它,这样可执行文件名就不再是第一个参数,而且这样就可以很好地工作

要运行cmd文件,请执行以下操作:

string theResponse = RunMyCmdAndGetResponse(@"c:\somepath\mycmd.cmd");

protected String RunMyCmdAndGetResponse(string cmdPath) {
    Process proc = new Process ();
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe";
    proc.StartInfo.Arguments = "/c cmd /c " + cmdPath;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.CreateNoWindow = true;

    proc.Start();
    proc.WaitForExit();
    string response = proc.StandardOutput.ReadToEnd();
    response += proc.StandardError.ReadToEnd();
    return response;
}
要运行脚本文件,请执行以下操作:

string theResponse = RunMyScriptAndGetResponse(@"c:\somepath\myscript.js");

protected String RunMyScriptAndGetResponse(string scriptPath) {
    Process proc = new Process ();
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe";
    proc.StartInfo.Arguments = "/c cscript //nologo " + scriptPath;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.CreateNoWindow = true;

    proc.Start();
    proc.WaitForExit();
    string response = proc.StandardOutput.ReadToEnd();
    response += proc.StandardError.ReadToEnd();
    return response;
}
不使用“cmd”怎么样


从ASPX页面运行批处理文件或任何进程都是徒劳的,因为IIS不能在真正的Windows用户上下文下运行。因此,无论您为用户提供了多少设置和权限,AppPool正在运行,或者您进行了任何类型的配置更改,它都不会工作。我很久以前也遇到过同样的问题,基本上这是不可能的

请参阅我之前的问题(和评论),以及您当前问题的可能“概念性”解决方案的公认答案,如下所示:


您试过这个吗?对不起,我刚注意到一些。。。请看下面我的答案。是的,我今天早上看了这些例子。我看到的最上面的答案和我上面的示例之间唯一的功能区别是,它们在读取StandardOutput和StandardError之前调用WaitForExit,而我在读取StandardOutput和StandardError之后调用WaitForExit。我只是试着在我的例子中做出改变,然后重新测试——没有乐趣!是的,我刚刚注意到您正在尝试在ASPX/AppPool上下文下执行此操作。。。这根本行不通。甚至cmd.exe也被视为一个UI应用程序,需要一个合适的用户上下文才能运行。是否还应将
StartInfo.RedirectStandardInput
设置为true?如果UseShellExecute为true,则该选项有效,但我需要UseShellExecute=false才能从cmd文件.Dang获取响应。我还尝试使用cscript.exe运行一个测试,并向它传递一个js脚本文件,但它也不会执行任何操作,因此它不是特定于exe.cmd的。我发现有趣的是,在这种情况下,“某些”东西似乎确实成功运行了:-我原来的选项1使用cmd.exe。正如@Derek所提到的,我还可以直接将cmd文件作为UseShellExecute=true的文件名提供,这也可以工作,尽管我无法得到这样的响应。我想我可以按Derek的方式运行它,让cmd将响应写入一个文件,然后用c#读取该文件,但这太难看了!是的,我知道。。。有些奇怪的事情对我起作用,但对我来说却不起作用!真的很难看。。。我不得不做一些非常时髦的事情来让我的流程也能正常工作。。。我必须在一个文本文件中写入一些东西,让一个windows服务在后台运行,然后从windows服务启动应用程序,而不是在我自己的帐户下,唤醒PC和各种奇怪的东西,以便能够从网页启动我的进程。。。真的很糟糕。谢谢你的帮助-你的意见让我找到了解决方案!用解决方案更新了我的原始问题。太棒了!:)很高兴它在某种程度上有所帮助:)我可能是错的,但我认为我上面的“RunMyCmdAndGetResponse”解决方案可能也可以运行您的exe文件,因为您正在尝试发布链接。您只需将其传递给exe文件的路径,而不是cmd文件的路径。当然,假设您的exe文件没有UI组件,等等。
string theResponse = RunMyScriptAndGetResponse(@"c:\somepath\myscript.js");

protected String RunMyScriptAndGetResponse(string scriptPath) {
    Process proc = new Process ();
    proc.StartInfo.FileName = @"c:\Windows\System32\cmd.exe";
    proc.StartInfo.Arguments = "/c cscript //nologo " + scriptPath;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.CreateNoWindow = true;

    proc.Start();
    proc.WaitForExit();
    string response = proc.StandardOutput.ReadToEnd();
    response += proc.StandardError.ReadToEnd();
    return response;
}
Process proc = new Process ();
proc.StartInfo.FileName = @"c:\mypath\myfile.cmd";