C# Process.Start cmd.exe赢得';t运行在IIS中运行时作为agument传递的cmd文件
我整个上午都在搜索和试验这个,我被难住了。我在IIS中运行了一个aspx页面,并调用以下c#函数。我试图让它运行一个cmd文件并返回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
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相同
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";