Laden...

ASP.NET - Process.Start() hängt fest

Letzter Beitrag vor 6 Jahren 5 Posts 1.438 Views
ASP.NET - Process.Start() hängt fest

[ASP.NET]
[C#]

Hallo liebes Forum,

ich habe eine interne Webanwendung die verschiedene Prozesse starten kann.
Ich nutze hier die PStools für z.B. Abfragen welche Benutzer gerade an einem Host angemeldet sind etc.

Nun soll das Ganze flexibel sein, sodass man eigene Skripts zur Datenbank hinzufügen kann und eine Art Script Sammlung bekommt. Soll uns Admins die Arbeit ein wenig abnehmen.

Solange ich das mit den PStools mache funktioniert alles wie gewünscht. Ich erhalte nach dem abgesetzten Befehl auch den Output. Gebe ich nun das Programm "cmd.exe" an und übergebe Parameter bekomme ich von meiner Website keinen Response mehr und die Ladeanimation dreht sich zu Tode. Er hängt genau bei

string output = sr.ReadToEnd();

fest.

Ich hoffe ihr habt eine Idee.
Ich steige nicht ganz dahinter warum die CMD sich so anders verhält... Probiere schon seit Stunden 😦

Hier mein Code wie ich die Prozesse starte:

 protected void btn_execute_Click(object sender, EventArgs e)
        {
            try
            {
                var command = (from TOOLBOX
                               in ADWM_DB_SETTINGS.TOOLBOX
                               where TOOLBOX.AKTION == ddl_command.SelectedValue.ToString()
                               select TOOLBOX).First();

                string ex_command = command.ARGUMENTE;

                if (txt_host.Text != "") ex_command = ex_command.Replace("%HOST%", txt_host.Text);
                if (txt_arguments.Text != "") ex_command = ex_command.Replace("%PARAMETER%", txt_arguments.Text);
                ex_command = ex_command.Replace("%USERNAME%", adw.GET_SETTING("EWS_USER"));
                ex_command = ex_command.Replace("%PASSWORD%", adw.GET_SETTING("EWS_PASSWORD"));

                Process p = new Process();
                p.StartInfo.UseShellExecute = false;

                if (File.Exists(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, @"Scripts\PStools\", command.PROGRAMM)))
                {
                    p.StartInfo.FileName = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, @"Scripts\PStools\", command.PROGRAMM);
                }
                else
                {
                    p.StartInfo.FileName = command.PROGRAMM;
                }

                p.StartInfo.Arguments = ex_command;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = true;
                p.Start();

                StreamReader sr = p.StandardOutput;
                StreamReader sr_err = p.StandardError;
                string output = sr.ReadToEnd();
                string output_err = sr_err.ReadToEnd();
                p.WaitForExit();

                if (output != "") txt_console_ouput.Text = output;
                else txt_console_ouput.Text = output_err;
            }
            catch (Exception ex)
            {
                txt_console_ouput.Text = ex.Message;
            }
        }

Grüße
trekki

Ich habe es noch mal etwas umgeschrieben, aber das Ergebnis ist genau das Gleiche, außer dass er nun bei

p.WaitForExit();

hängt.

Hier die andere Version:


protected void btn_execute_Click(object sender, EventArgs e)
        {
            try
            {
                var command = (from TOOLBOX
                               in ADWM_DB_SETTINGS.TOOLBOX
                               where TOOLBOX.AKTION == ddl_command.SelectedValue.ToString()
                               select TOOLBOX).First();

                string ex_command = command.ARGUMENTE;

                if (txt_host.Text != "") ex_command = ex_command.Replace("%HOST%", txt_host.Text);
                if (txt_arguments.Text != "") ex_command = ex_command.Replace("%PARAMETER%", txt_arguments.Text);
                ex_command = ex_command.Replace("%USERNAME%", adw.GET_SETTING("EWS_USER"));
                ex_command = ex_command.Replace("%PASSWORD%", adw.GET_SETTING("EWS_PASSWORD"));

                Process p = new Process();
                p.StartInfo.UseShellExecute = false;

                if (File.Exists(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, @"Scripts\PStools\", command.PROGRAMM)))
                {
                    p.StartInfo.FileName = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, @"Scripts\PStools\", command.PROGRAMM);
                }
                else
                {
                    p.StartInfo.FileName = command.PROGRAMM;
                }

                p.StartInfo.Arguments = ex_command;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = true;
                p.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
                p.ErrorDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
                p.Start();
                p.BeginOutputReadLine();
                p.WaitForExit();

                /*StreamReader sr = p.StandardOutput;
                StreamReader sr_err = p.StandardError;
                string output = sr.ReadToEnd();
                string output_err = sr_err.ReadToEnd();
                p.WaitForExit();*/

                /*if (output != "") txt_console_ouput.Text = output;
                else txt_console_ouput.Text = output_err;*/
            }
            catch (Exception ex)
            {
                outputData.Append(ex.Message);
            }
            finally { txt_console_ouput.Text = outputData.ToString(); }
        }

        protected void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                outputData.AppendLine(e.Data.ToString());
            }
        }

Gruß
trekki

Ist der Prozess denn wirklich beendet oder wartet cmd.exe noch auf einen "exit"-Befehl?
Manchmal liegt's ja auch schon an solchen Kleinigkeiten.

Völlig falsches Vorgehen: eine Anwendung im IIS muss immer isoliert sein und darf nie was auf der Maschine ausführen. NIE!
Das liegt allein schon an der Tatsache, dass die IIS Umgebung in einer Art Sandbox laufen soll und dementsprechend auch die Rechte runter gestrippt sind.
Und wenn ich hier in der Ausführung auch noch Credentials seh...

Besser:
einen Windows Service entwickeln, der die Aufgaben übernimmt.
ASP.NET spricht dann mit einem RESTful Endpunkt des Windows Service.

@pinki: Exit Befehl hört sich schon mal gut an... Ich rufe mit dem Process.Start ja cmd.exe und die Argumente auf. Da steht kein exit dann irgendwo. Der Befehl, wie z.B. mkdir wird ja abgesendet und gleich umgesetzt. Ich kenn das aus Skriptdateien mit dem Exit damit die Konsolenfenster sich schließt. Muss ich mal näher untersuchen.

@Abt: Was spricht dagegen wenn es nur eine Intranetanwendung ist? Außerdem kann ich doch dem IIS App Pool jeden Nutzer zuweisen den ich will? Wird dann in diesem Nutzerkontext ausgeführt.

Gruß
trekki