C#从网站按钮运行CMD [英] C# Run CMD from website button

查看:89
本文介绍了C#从网站按钮运行CMD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我玩Terraria。我有时主持游戏。我希望用户能够随时获取我的世界的当前地图。所以我创建了一个简单的网页,使用MoreTerra(一个地图软件)为我创建一个背景地图和一个向用户显示地图的网页。



MoreTerra附带了一个从命令行运行的批处理文件。批处理文件包含以下内容:



 @ ECHO OFF 
cmd.exe / c MoreTerra.exe%1%2% 3%4
@ECHO ON





我想在用户点击我的按钮时执行此操作网页,所以我创建了以下代码:



 尝试 
{
// 声明变量
string worldFile = \ + AppSettings.GetAppSetting(< span class =code-string> WorldFile false )+ \;
string outputLocation = \ + AppSettings.GetAppSetting( OutputLocation false )+ @ \ + AppSettings.GetAppSetting( ImageFileName false )+ \;
string fileName = AppSettings.GetAppSetting( MT_Location false )+ @ \ + MoreTerraNoGui.bat;
ProcessStartInfo si = new ProcessStartInfo();
// 定义StartInfo
si.FileName = @ C:\ Windows \ SysWOW64 \ cmd.exe;
si.Arguments = / c + fileName + -w + worldFile + -o + outputLocation;
si.WorkingDirectory = AppSettings.GetAppSetting( MT_Location);
si.CreateNoWindow = true ;
si.WindowStyle = ProcessWindowStyle.Hidden;
si.UseShellExecute = false ;
si.RedirectStandardOutput = true ;
si.RedirectStandardError = true ;
// 调试检查的日志参数
Log.WriteToLog(ProjectLogType,< span class =code-string>
btnRefresh_Click,si.Arguments,LogEnum.Debug);
// 启动流程并等待它完成
流程subProcess =流程。开始(SI);
subProcess.WaitForExit();
// 日志输出和错误
string output = subProcess.StandardOutput.ReadToEnd();
string error = subProcess.StandardError.ReadToEnd();
Log.WriteToLog(ProjectLogType, btnRefresh_Click,output,LogEnum.Debug);
Log.WriteToLog(ProjectLogType, btnRefresh_Click,error,LogEnum.Debug);
}
catch (例外x)
{
Log.WriteToLog(ProjectLogType, btnRefresh_Click,x,LogEnum.Critical);
}





到目前为止它还没有真正做任何事情。在任务管理器中,每次单击按钮时,我都会看到控制台窗口主机进程在不到一秒的时间内启动和停止,但不会生成任何图像。输出和错误变量始终为空。但是当我在subProcess.WaitForExit();调试并中断时我可以在Visual Studio的Locals窗口中看到这个错误



  -  MainModule'subLrocess.MainModule'抛出类型为'System'的异常.ComponentModel.Win32Exception'System.Diagnostics.ProcessModule {System.ComponentModel.Win32Exception} 
+ base {32位进程无法访问64位进程的模块。} System.Runtime.InteropServices.ExternalException {System。 ComponentModel.Win32Exception}
NativeErrorCode 299 int





我尝试在C#代码中使用相同的cmd.exe在批处理文件中,x86和x64,但无济于事。

我使用corflags.exe来检查MoreTerra.exe,它不是32bit所需,我的代码是为AnyCPU编译的,所以我真的很亏。

我一直在网上搜索,但我发现的所有内容都包含在上面的代码中。



任何帮助都会很大赞赏。 TIA

解决方案

 cmd.exe / c MoreTerra.exe%1%2%3%4 

make没有任何意义。你只需要

 MoreTerra.exe%1%2%3%4 





启动MoreTerra.exe%1%2%3%4 



开始不同:它启动应用程序而不是等待终止。



明白:CMD.EXE与启动任何进程无关。这是一个你需要手动使用的命令解释器。



在C#中代码:

 < span class =code-keyword> string  exe =   MoreTerra.exe;  //  但您确实需要计算其路径名 
字符串 first = // ...
字符串 second = // ...
string third = // ...
string forth = // .. 。
System.Diagnostics.Start(exe, string .Format( {0} {1} {2} {3},第一,第二,第三,第四));



-SA


建议只在计划任务中使用批处理文件并让网站显示生成的图像e而不是冒着多个用户单击网站上的刷新按钮的流程垃圾邮件,在另一个我也问过这个问题的论坛中。问题解决了。我在地图显示页面添加了一个变量,从生成的文件和繁荣中拉出最后更新的日期。感谢您对Start vs CMD.exe的所有建议和课程


请尝试使用此行:

 si.FileName =  @  cmd.exe;  //  操作系统将选择写入cmd为32/64位 


I play Terraria. I host games sometimes. I want users to be able to grab a current map of my world, whenever they want to. So I created a simple web page to use MoreTerra (a mapping software) to create a map in the background for me and a web page to display the map to users.

MoreTerra comes with a batch file that runs itself from the command line. the batchfile contains the following:

@ECHO OFF
cmd.exe /c MoreTerra.exe %1 %2 %3 %4
@ECHO ON



I want to execute this when a user clicks a button on my web page, so I created the following code:

try
           {
               // declare variables
               string worldFile = "\"" + AppSettings.GetAppSetting("WorldFile", false) + "\"";
               string outputLocation = "\"" + AppSettings.GetAppSetting("OutputLocation", false) + @"\" + AppSettings.GetAppSetting("ImageFileName", false) + "\"";
               string fileName = AppSettings.GetAppSetting("MT_Location", false) + @"\" + "MoreTerraNoGui.bat";
               ProcessStartInfo si = new ProcessStartInfo();
               // define StartInfo
               si.FileName = @"C:\Windows\SysWOW64\cmd.exe";
               si.Arguments = "/c " + fileName + " -w " + worldFile + " -o " + outputLocation;
               si.WorkingDirectory = AppSettings.GetAppSetting("MT_Location", false);
               si.CreateNoWindow = true;
               si.WindowStyle = ProcessWindowStyle.Hidden;
               si.UseShellExecute = false;
               si.RedirectStandardOutput = true;
               si.RedirectStandardError = true;
               // log arguments for debug check
               Log.WriteToLog(ProjectLogType, "btnRefresh_Click", si.Arguments, LogEnum.Debug);
               // start process and wait for it to finish
               Process subProcess = Process.Start(si);
               subProcess.WaitForExit();
               // log output and errors
               string output = subProcess.StandardOutput.ReadToEnd();
               string error = subProcess.StandardError.ReadToEnd();
               Log.WriteToLog(ProjectLogType, "btnRefresh_Click", output, LogEnum.Debug);
               Log.WriteToLog(ProjectLogType, "btnRefresh_Click", error, LogEnum.Debug);
           }
           catch(Exception x)
           {
               Log.WriteToLog(ProjectLogType, "btnRefresh_Click", x, LogEnum.Critical);
           }



So far it hasn't really done anything. In the Task Manager, I can see Console Window Host process start and stop in less than a second every time I click the button, but no image is generated. The Output and Error variables are always empty. but when I debug and break at "subProcess.WaitForExit();" I can see this error in the Locals Window in Visual Studio

-       MainModule  'subProcess.MainModule' threw an exception of type 'System.ComponentModel.Win32Exception'   System.Diagnostics.ProcessModule {System.ComponentModel.Win32Exception}
+       base    {"A 32 bit processes cannot access modules of a 64 bit process."}   System.Runtime.InteropServices.ExternalException {System.ComponentModel.Win32Exception}
        NativeErrorCode 299 int



I've tried using the same cmd.exe in both the C# code and in the batch file, both x86, and x64, but to no avail.
I used corflags.exe to check MoreTerra.exe, and it's not 32bit required, my code is compiled for AnyCPU, so I'm at a real loss.
I've been scouring the internet, but everything I've found is incorporated into the above code.

Any help would be greatly appreciated. TIA

解决方案

cmd.exe /c MoreTerra.exe %1 %2 %3 %4

makes no sense at all. You need simply

MoreTerra.exe %1 %2 %3 %4


or

start MoreTerra.exe %1 %2 %3 %4


Start is different: it starts the application and does not wait for its termination.

Do understand: CMD.EXE has nothing to do with starting any process. This is a command interpreter which you only need for manual use.

In C# code:

string exe = "MoreTerra.exe"; // but you really need to CALCULATE its path name
string first = //...
string second = //...
string third = //...
string forth = //...
System.Diagnostics.Start(exe, string.Format("{0} {1} {2} {3}", first, second, third, forth));


—SA


It was suggested to just use the batch file in a Scheduled Task and have the website show the generated image rather than risk the process spam of multiple users clicking the refresh button on the website, in another forum that I also asked this question in. Problem solved. I added a variable to the map display page to pull the last updated date from the generated file and boom, done. Thanks for all the advice and the lesson on Start vs CMD.exe


Try this line instead :

si.FileName = @"cmd.exe"; // the OS will select the write cmd for 32/64 bit


这篇关于C#从网站按钮运行CMD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆