Foo.cmd will not output lines in the process (on the website)

I have a problem with understanding in and out of the ProcessStartInfo class in .NET. I use this class to execute .exe programs like FFmpeg without any problems.

But when I use ProcessStartInfo to run the .cmd program, as a simple foo.cmd file containing only @echo Hello world , it does not output anything.

  ProcessStartInfo oInfo = new ProcessStartInfo(@"C:\Program Files (x86)\itms\foo.cmd") { UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, CreateNoWindow = true }; using (Process p = new Process()) { p.StartInfo = oInfo; p.OutputDataReceived += new DataReceivedEventHandler(transporter_OutputDataReceived); p.Start(); p.BeginOutputReadLine(); p.WaitForExit(); } private void transporter_OutputDataReceived(object sender, DataReceivedEventArgs e) { Response.Write(e.Data + " - line<br/>"); } 

I have seen many examples where people use cmd.exe to run the .cmd program, and I tried this, but to no avail. The program simply continues to load endlessly.

  ProcessStartInfo oInfo = new ProcessStartInfo("cmd", "/c start foo.cmd") { UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, CreateNoWindow = true, WorkingDirectory = @"C:\Program Files (x86)\itms" }; 

The foo.cmd program works and displays successfully using the command line tool on Windows and Mac.

Maybe someone wants to demystify this for me.

thanks

EDIT

The code runs correctly when executed locally. The problem occurs when I execute the code on our website. Either the program cannot be executed, or the output is somehow disabled.

Only cmd.exe returns the output '' cmd "," / c dir " is, for example, returning information about the current contents of the folder.

Could this be a resolution problem?

+7
source share
3 answers

I myself have found the answer and will post the solution for everyone who is interested.

The source of the problem is quite difficult to debug, because the problem arose in how IIS handles users and processes.

As I thought, there was nothing wrong with the code.

Answer

In IIS, the website runs in AppPool. AppPool is assigned a user ID. The default identifier is a virtual built-in account named ApplicationPoolIdentity . This user does not have privileges to call any (as far as I know) external batch / command line scripts.

Providing the username, password and domain for the administrative user when starting a new process did not help me solve. Perhaps I just do not understand the whole concept.

Using <identity impersonate="true" userName="domain\user" password="pass" /> in webconfig did not solve anything. This is apparently due to the fact that the AppPool designated user is still the author of all the processes.

What really beat me was that I could execute .exe files, but not .cmd or .bat files.

The solution for me was to create a new user with privileges to execute batch scripts and select that user as the AppPool user in IIS.

Change As I mentioned in the comments, the user I'm working with is created on the Active Directory server, since this particular file server is located in a network share. The user is part of the local IIS_IUSRS server group on my web server and has read / write / execute permissions in the folder in which executable programs are stored.

Edit2: the solution works for local user accounts, and as long as the user is part of the local IIS_IUSRS server group and has read / write / execute permissions in the folder where the executable programs are saved.

+11
source

This is slightly modified code, but it should give you a better idea of ​​the class.

 ProcessStartInfo info = new ProcessStartInfo(); info.Arguments = "/CC:\Program Files (x86)\itms\foo.cmd"; info.WindowStyle = ProcessWindowStyle.Hidden; info.CreateNoWindow = true; info.FileName = "cmd.exe"; // or C:\Program Files (x86)\itms\foo.cmd with no info.Arguments info.UseShellExecute = false; info.RedirectStandardOutput = true; using (Process process = Process.Start(info)) { using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.WriteLine(result); } } 

This will redirect the cmd window output to the console, just adjust as needed.

0
source

you will need to use it that way

  using (Process p = Process.Start(oInfo)) { ..... 

The reason is that Process.Start () and Process.Star (startinfo) work a little differently

Process.Start () - starts (or reuses) a process resource that is specified by the StartInfo property of this Process component and binds it to the component.

Return value

Type: System.Boolean true if the process resource is running; false if a new process resource does not start (for example, if an existing process is reused).

Process.Start (StartInfo) - starts a process resource that is specified by a parameter containing information about the beginning of the process (for example, the file name for starting the process) and associates the resource with a new process component.

Return value

Type: System.Diagnostics.Process A new process component that is associated with a process resource, or null if there is no process resource (for example, if an existing process is reused).

0
source

All Articles