Laden...

Ext. Konsolenprogramm starten und nicht schließen lassen

Erstellt von da_user vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.241 Views
D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren
Ext. Konsolenprogramm starten und nicht schließen lassen

Hi,

ich weiß nicht, ob ich das innerhalb von C# realisieren muss, oder ob ich auf einen anderen Trick zugreifen muss.
Mein Problem ist eigentlich relativ simpel, ich starte ein ext. Konsolenprogramm:

        private void RunApache()
        {
            string ApachePath = Path.Combine(WorkingDir, "server", "mapache.exe");
            System.Diagnostics.Process.Start(ApachePath, "/B");
        }

Dieses Konsolenprogramm (gut, Apache) taucht dann auch auf, spuckt mir jede Menge Text aus und schließt sich. Letzteres sollte nicht passieren, also gehe ich davon aus, dass dem Apache irgendwas nicht passt. Was? Keine Ahnung, so schnell kann ich nicht lesen!

Gibts einen Trick, wie ich verhindere dass sich das Konsolenfenster gleich wieder schließt, sobald der Apache beendet ist?

VG
da_user

D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren

Ok, eigentlich hätte ich das pl-pl im Link nicht durch de-de ersetzen müssen. 😉

"Console.Read" ist ja prinzipiell bekannt, aber in wie weit hilft mir das jetzt weiter? Ich kenne das jetzt in einem mir ähnlichen Anwendungsfall nur dazu, um zu sorgen dass sich das Fenster MEINER Konsolenanwendung nicht schließt. Ich will aber, dass sich das Fenster einer externen durch "Process.Start" gestarteten Konsolenanwendung nicht schließt.
In die kann ich schlechte ein "Console.Read" einbauen.

Oder kann ich diese Methode irgendwie dazu benutzen, die Ausgabe dieser ext. Konsolenanwendung einzulesen und in meinem Programm zu verarbeiten?

VG
da_user

301 Beiträge seit 2009
vor 5 Jahren

Achso da habe ich deine Anforderung wohl missverstanden.

Meines Wissens nach geht das nicht. Zumindest fände ich es besorgniserregend wenn es irgendwie möglich wäre.

Was du aber ggf. tun möchtest ist den ExitCode der Anwendung die du gestartet hast mitbekommen? Du hast nicht wirklich klar gemacht wofür du das ganze tun möchtest.

https://docs.microsoft.com/de-de/dotnet/api/system.diagnostics.process.exitcode?view=netframework-4.7.2

D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren

Achso da habe ich deine Anforderung wohl missverstanden.

Kein Problem 😉

Ob mir der Exit-Code weiterhilft? Ich werde es morgen mal probieren.

Du hast nicht wirklich klar gemacht wofür du das ganze tun möchtest.

Der Apache soll ja eigentlich schön fröhlich im Hintergrund vor sich hinlaufen. Macht er aber nicht, er zeigt ganz schnell einen guten Schwung Text an, und schließt dann wieder. Ich vermute stark, dass in dem Text drinsteht, was ihm da nicht passt, bin aber nicht schnell genug, diesen zu lesen.

Edit:
Ich bin jetzt (erst!) tatsächlich auf die Idee gekommen, den Apache mal über die CMD zu starten. Ergebnis: der Parameter "/B" ist falsch. Habe ich aus einer Batch-File und bezieht sich dort auf den "start" Befehl.
Ohne den Parameter läuft er aus der CMD, aus dem C#-Programm leider nicht. Da habe ich jetzt immer noch das Problem, dass der zu schnell schließt um die Ausgabe lesen zu können.

2.078 Beiträge seit 2012
vor 5 Jahren

Ganz unschuldig gefragt:

Was hast Du vor und wäre es vielleicht besser, den Apache direkt als Windows-Dienst laufen zu lassen?
Das klingt danach, als würde es genau das erklären:
https://httpd.apache.org/docs/2.4/platform/windows.html#winsvc

D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren

Hi,

"eigentlich" relativ einfach.
Es gibt das DokuWiki welches es auch in einer "on a Stick" Variante gibt, mit einem minimalen Apache-Server der vom Prinzip wie eine Portable-App läuft. Problematisch ist, dass der nur von einem echten lokalen Verzeichnis läuft, ich das DokuWiki aber in einem Netzwerkverzeichnis ablegen möchte.
Ich habe mir jetzt die mitgelieferte Batch soweit angepasst, dass ich "nur" noch den Apache in ein lokales Verzeichnis kopieren muss, die Batch mapt mir dann das Netzwerkverzeichnis auf ein Netzlaufwerk und hinterlegt den Pfad dazu in einer Umgebungsvariable unter HKEY_CurrentUser (oder so ähnl.). Diese Umgebungsvariable habe ich in der ConfigDatei des Apache als "DocumentRoot" hinterlegt.
Mit der Batch funktioniert das ganze schonmal ganz gut und auch ziemlich stabil. Proof-of-Concept steht somit eigentlich soweit. Problematisch ist halt, dass das ganze noch nicht so komfortabel ist, wie ich es gerne hätte und es noch das eine oder andere Feature gäbe, dass ich da noch rein bringen würde. So ist z.B. zum sauberen beenden immer eine Benutzeraktion notwendig. Fenster der Batch-File schließen reicht nicht, macht man aber intuitiv.
Das geht halt mit einem "ordentlichen" Programm schöner, besser und übersichtlicher.
Ich würde auch nicht davon ausgehen, dass der Nutzer die Rechte hat, einen Dienst zu erstellen/starten.

Was mir hierbei kommt:
Die Umgebungsvariable setze ich mit der Option "EnvironmentVariableTarget.User", also nur für den Benutzer, da ich nicht davon ausgehe, Umgebungsvariablen für die komplette Maschine setzen zu dürfen. Process.Start startet aber m.W. Anwendungen mit anderen Rechten als die meinige Anwendung. Kann es da sein, dass der Apache-Server den ich über mein Programm starte, gar nix von der Umgebungsvariable wissen kann?
Auskunft dazu würde mir halt die Ausgabe geben, aber an die muss ich erstmal rankommen...

VG
da_user

87 Beiträge seit 2016
vor 5 Jahren

Hallo,

die Ausgabe der Kommandozeile kann man in eine Textdatei umleiten. Vielleicht funktioniert das ja auch bei deinem Aufruf.

glandorf

S
324 Beiträge seit 2007
vor 5 Jahren

Mal eine andere Idee bzgl des Vorhabens.
Wenn es sich hier "nur" um das Bereitstellen eines Dokuwikis handelt, dann muss man keinen kompletten Apache nutzen.
PHP hat seit der Version 5.4 einen eingebauten Webserver (http://php.net/manual/de/features.commandline.webserver.php) welcher zumidnest zum Bereitstellen eines Dokuwikis taugt.

Der Aufruf würde dann so aussehen (I:\ ist in dem Fall mein USBStick ):

I:\WikiApp\php.exe -S 0.0.0.0:3002 -t I:\WikiApp\www

Dann läuft der in PHP eingebaute Webserver auf Port 3002 und das Dokuwiki liegt in meinem Fall auf dem USB Stick in I:\WikiApp\www.

Mit nssm (https://nssm.cc/) kannst du das ganze auch als Dienst einrichten:

nssm install WikiApppUSB I:\WikiApp\php.exe -S 0.0.0.0:3002 -t I:\WikiApp\www

Du kannst das ganze auch fertig unter http://fossilrepos.sourceforge.net/srv.fsl/23/home herunterladen. Allerdings solltest du es nur lokal nutzen, da das php darin echt schon sehr alt ist 😃

16.806 Beiträge seit 2008
vor 5 Jahren

Hinweis: der Webserver in PHP ist explizit nur für die Entwicklung gedacht; nicht zum hosten einer Anwendung.

@da_user wie in den anderen Threads schon angemerkt: meinst Du nicht, dass Du Dich nicht mittlerweile enorm verrannt hast?
Du stolperst hier von einem in das andere Problem, weil Du einer Lösung nachläufst, die quasi einer extrem instabile, aufwändige Bastellösung gleicht.

Hättest Du evtl. ein paar Stunden in ein Konzept gesteckt, hättest Du Dir viel Zeit und Ärger sparen und dabei Dein Wiki sauber hosten können 😉

D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren

die Ausgabe der Kommandozeile kann man in eine Textdatei umleiten. Vielleicht funktioniert das ja auch bei deinem Aufruf.

Guter Tipp! Umleiten der Standardausgabe hat nicht gereicht, aber die der Errorausgabe:

            Process ApacheServer = new Process();
            ApacheServer.StartInfo.FileName = ApachePath;
            ApacheServer.StartInfo.UseShellExecute = false;
            ApacheServer.StartInfo.RedirectStandardOutput = true;
            ApacheServer.StartInfo.RedirectStandardError = true;

            ApacheServer.Start();

            string stdOut = ApacheServer.StandardOutput.ReadToEnd();
            string erOut = ApacheServer.StandardError.ReadToEnd();

Dann erhalte ich diese Fehlermeldung:> Fehlermeldung:

mapache.exe: Syntax error on line 13 of Z:/server/conf/httpd.conf: Cannot load php/ssleay32.dll into server: Das angegebene Modul wurde nicht gefunden.

Ich habe im Moment zwar noch keine Ahnung, was ich mit dieser Fehlermeldung anfangen soll, das dürfte google jetzt dann aber hoffentlich richten 😉

Wenn es sich hier "nur" um das Bereitstellen eines Dokuwikis handelt, dann muss man keinen kompletten Apache nutzen.
PHP hat seit der Version 5.4 einen eingebauten Webserver (
>
) welcher zumidnest zum Bereitstellen eines Dokuwikis taugt.

Danke für den Hinweis. Ich brauche halt einen Server, der nicht nur vom USB-Stick sauber startet, sondern auch aus einem Netzwerkverzeichnis, oder alternativ Netzlaufwerk. (@"\Server\Wiki\php.exe -S 0.0.0.0:3002 -t \Server\Wiki\www").
Könntest du das evtl. probieren?

Hinweis: der Webserver in PHP ist explizit nur für die Entwicklung gedacht; nicht zum hosten einer Anwendung.

Meist bezieht sich das ja zum Glück auf fehlende Sicherheit. Da der Server nur lokal verfügbar sein soll, kann ich das zum Glück eher missachten.

@da_user wie in den anderen Threads schon angemerkt: meinst Du nicht, dass Du Dich nicht mittlerweile enorm verrannt hast?
Du stolperst hier von einem in das andere Problem, weil Du einer Lösung nachläufst, die quasi einer extrem instabile, aufwändige Bastellösung gleicht.

Hättest Du evtl. ein paar Stunden in ein Konzept gesteckt, hättest Du Dir viel Zeit und Ärger sparen und dabei Dein Wiki sauber hosten können 😉

Wenn ich den in meinem Netzwerk betreiben wollen würde, hätte ich das Wiki schon längst sauber gehostet. Ist es halt leider nicht.
Und wenn ich gleich zum basteln angefangen hätte, hätte ich jetzt noch jede Menge Zeit und Nerven übrig.
Das läuft sowieso eher so nebenbei. Prinzipiell läuft das ganze ja schon mit der Batchfile-Lösung so dass man damit gut arbeiten kann. Hat mich bis dato weder viele Stunde noch großartig Nerven gekostet. Und sollte ich doch mal einen ordentlichen Serverplatz bekommen, kann ich ja zum Glück bequem umziehen 😉

D
da_user Themenstarter:in
94 Beiträge seit 2008
vor 5 Jahren

Hi,
passt, geklärt. das "WorkingDirectory" hat nicht gestimmt.
Aufruf sieht jetzt so aus:

            ApacheServer = new Process();
            ApacheServer.StartInfo.FileName = Path.Combine(WorkingDir, "server", "mapache.exe");
            ApacheServer.StartInfo.EnvironmentVariables["DOKUWIKI_ROOT"] = WorkingDir;
            ApacheServer.StartInfo.WorkingDirectory = Path.Combine(WorkingDir, "server");
            ApacheServer.StartInfo.CreateNoWindow = true;
            ApacheServer.StartInfo.UseShellExecute = false;
            ApacheServer.StartInfo.RedirectStandardOutput = true;
            ApacheServer.StartInfo.RedirectStandardError = true;

            ApacheServer.Start();

            string stdOut = ApacheServer.StandardOutput.ReadToEnd();
            string erOut = ApacheServer.StandardError.ReadToEnd();

Die Umleitung des ErrorStreams werde ich wohl drinnenlassen, kann man sicherlich gut gebrauchen, um einen Fehler zu werfen 😉

Danke!