Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Applikationen aus ASP.NET ausführen

Geschrieben von: Christoph Wille
Kategorie: ASP.NET

This printed page brought to you by AlphaSierraPapa

Irgendwo gibt es immer eine kleine Kommandozeilenapplikation, die etwas kann, was keine Komponente kann. Und dann taucht die Frage auf, wie man dieses Programm aus ASP.NET heraus starten, und den Output dann weiterverwenden kann.

Unter ASP gibt's die AspExec Gratiskomponente von ServerObjects, die im Artikel Mailadressen-überprüfen für Fortgeschrittene beschrieben ist. Obwohl man diese Komponente theoretisch unter ASP.NET einsetzen könnte, rate ich wie immer von nicht-managed Lösungen ab - sie sind zu langsam.

Daher muß ich wohl oder übel eine managed Lösung präsentieren, oder?

Da ich ja in die Entwicklung von SharpDevelop eingebunden bin, habe ich beim Code Review einiges über die verschiedenen "versteckten" Klassen gelernt - weil wer bitte kommt auf die Idee, eine Klasse zur Ausführung von Programmen im Namespace für Compiler zu verstecken? Dort findet sie nun wirklich kein normaler Mensch!

Die Klasse, die uns interessiert, ist Executor, die sich im System.CodeDom.Compiler Namespace versteckt. Diese bietet die Methode ExecWaitWithCapture (der Name sagt ja fast alles), welche wir sogleich in eine wiederverwendbare Funktion für uns verpacken:

// execute an application, return output string
string ExecuteCmdLineApp(string strCmd)
{
  string output = "";
  string error  = "";

  TempFileCollection tf = new TempFileCollection();
  Executor.ExecWaitWithCapture(strCmd, tf, ref output, ref error);

  StreamReader sr = File.OpenText(output);
  StringBuilder strBuilder = new StringBuilder();
  string strLine = null;

  while (null != (strLine = sr.ReadLine()))
  {
    if ("" != strLine)
    {
      strBuilder.Append(strLine);
      strBuilder.Append("\r\n");
    }
  }
  sr.Close();

  File.Delete(output);
  File.Delete(error);

  return strBuilder.ToString();
}

Der meiste Code kommt von der speziellen Art der Verwendung der ExecWaitWithCapture Methode. Diese schreibt den Output als auch die Fehler in temporäre Dateien, die man auslesen kann. Die Dateien kommen als TempFileCollection Parameter in die Methode, die Namen der Dateien als zwei String Parameter retour. Der erste Parameter ist wenigstens von Anfang an klar - die Befehlszeile der Applikation, deren Output gecaptured werden soll.

Da der Output in einer Datei landet, muß ich diese auch wieder auslesen. Dazu verwende ich einen StreamReader als auch einen StringBuilder. Gründe für diese Vorgehensweise finden sich im Artikel Dateien lesen in ASP.NET.

Eine wichtige Information muß ich noch weitergeben: wie man aus dem Sourcecode ersehen kann, lösche ich Leerzeilen aus dem Output. Wer dies nicht möchte, sollte auf folgende Eigenheit der Executor Klasse aufpassen: ein Carriage Return/Line Feed Paar im Output des Programms wird in ein solches plus eine Leerzeile umgesetzt!

Ein wichtiger Part fehlt uns noch, um die Funktion zumindest theoretisch zum funktionieren zu bringen - die Namespace Import Statements:

<% @Import Namespace="System.IO" %>
<% @Import Namespace="System.Text" %>
<% @Import Namespace="System.CodeDom.Compiler" %>

Nun bauen wir uns noch ein highly sophisticated User Interface:

<form runat="server" method="post">
Kommando: <asp:TextBox id="txtCommand" runat="server" 
    value="ping localhost" size=30 />
<asp:Button id="btnSubmit" text="Kommando ausführen" 
    onClick="btnSubmit_Click" 
    runat="server" />

<pre>
<asp:Label id="txtResult" runat="server" />
</pre>

</form>

und verdrahten die Schaltfläche zur entsprechenden Event Methode:

void btnSubmit_Click(Object Sender, EventArgs E)
{
  string strResult = "Error";
  try
  {
    strResult = ExecuteCmdLineApp(txtCommand.Text);
  }
  catch(Exception e)
  {
    strResult = e.ToString();
  }
  txtResult.Text = strResult;
}

Das wär's. Sogar Exceptions werden jetzt behandelt (Programm existiert nicht, oder ein Fehler irgendeiner anderen Art).

Natürlich erproben wir unser highly sophisticated User Interface mit einer ebensolchen Applikation: ping.exe. Hier der entsprechende Screenshot:

Der Grund, warum ich die Leerzeilen alle gelöscht habe? Den Output der Applikation wird der Benutzer sowieso nur in den seltensten Fällen zu Gesicht bekommen - weil die ASP.NET Seite den Output aufparst und die wichtigen Infos herausfiltert - für die Weiterverwendung.

Schlußbemerkung

Oft findet man wichtige Funktionalitäten gerade dort, wo man sie nicht vermuten würde, und wo schon gar nicht gesucht hätte. Daher mein Rat: einen Tag Zeit nehmen, und nur die .NET Reference durchklicken, damit man einen Überblick bekommt, welcher Namespace welche Funktionalitäten zur Verfügung stellt.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010220.zip

Verwandte Artikel

Dateien lesen in ASP.NET
http:/www.aspheute.com/artikel/20000929.htm
Kommandozeilen-Programme aufrufen
http:/www.aspheute.com/artikel/20010516.htm
Mailadressen-überprüfen für Fortgeschrittene
http:/www.aspheute.com/artikel/20000822.htm
Schluß mit lustig Teil 3 - das Hfnetchk Tool
http:/www.aspheute.com/artikel/20010928.htm

Links zu anderen Sites

ServerObjects
http://www.serverobjects.com/
SharpDevelop
http://www.icsharpcode.net/OpenSource/SD/

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.