Ist es möglich, erstellen Sie eine Konsolenanwendung, die nicht-Anzeige einer Konsole-Fenster, wenn Sie doppelt geklickt?

Verwandte:

Sollte ich auch ein command-line-Modus für meine Anwendungen?

Wie greifen übergeordnete Prozess-standard-Ausgabe?

Kann eine Konsole-Anwendung erkennen, ob es ausgeführt wurde, aus dem Explorer?

Will ich bauen eine Konsole app, die normalerweise von der Kommandozeile aus gestartet.

Aber, wenn es per Doppelklick im Explorer (im Gegensatz zu der Ausführung von einem cmd.exe Eingabeaufforderung), dann möchte ich das Programm NICHT angezeigt, ein Konsolen-Fenster.

Ich dies vermeiden wollen:

Ist es möglich, erstellen Sie eine Konsolenanwendung, die nicht-Anzeige einer Konsole-Fenster, wenn Sie doppelt geklickt?

Ist es möglich?

BEARBEITEN ich denke, eine andere Art zu Fragen, ist es, ist es möglich, ein Programm zu wissen, wie es aufgerufen wurde - ob per Doppelklick oder per Kommandozeile ?

Ich arbeite in .NET auf Windows.

EDIT 2: Von dieses Old New Thing blog-Beitrag lernte ich einige gute Sachen. Hier ist, was ich jetzt weiß...

In Windows EXE-Dateien werden markiert als entweder GUI oder nicht GUI. Mit csc.exe ist diese Option aktiviert mit /target:winexe oder /target:exe. Bevor die erste Anweisung im Prozess ausgeführt wird, der Windows-kernel stellt die Ausführungsumgebung. In diesem moment, wenn die EXE-Datei ist markiert GUI den kernel setzt die stdin/stdout für den Prozess auf NULL, und wenn nicht-GUI (Kommando-Zeile) der kernel erstellt eine Konsole und legt die stdin/stdout für den Prozess, der zu dieser Konsole.

Beim starten des Prozesses, wenn es kein stdin/stdout (== /target:winexe), dann wird der Anruf sofort zurück. Also, starten Sie eine gui-app aus cmd.exe Sie erhalten sofort Ihre cmd-Eingabeaufforderung zurück. Wenn es ein stdin/stdout, und wenn Sie laufen aus cmd.exe, dann die Eltern cmd.exe wartet auf Prozess beenden.

Die "sofortige Rückgabe" ist wichtig, denn wenn man code eine GUI-app zu befestigen, um seine Eltern-Konsole, werden Sie in der Lage, das zu tun-Konsole.writeline, etc. Aber die cmd.exe Eingabeaufforderung aktiv ist. Der Benutzer kann neue Befehle, einen neuen Prozess starten, und so weiter. In anderen Worten, von einem winexe, einfach Anbringung an der übergeordneten Konsole mit AttachConsole(-1) wird nicht "turn it in" a console app.


In diesem Punkt denke ich, dass der einzige Weg, um eine app zu verwenden die Konsole, wenn es aus aufgerufen wird cmd.exe und NICHT es verwenden, wenn es doppelt geklickt wird, definieren Sie die exe-Datei als reguläre Konsole exe (/target:exe), und Fenster verstecken auf Start, wenn angemessen. Sie erhalten immer noch eine Konsole-Fenster erscheint kurz.

Ich habe noch nicht herausgefunden, wie man weiß, ob es ins Leben gerufen wurde Sie vom explorer oder cmd.exe, aber ich bin immer näher..


ANTWORTEN

Es ist nicht möglich, erstellen Sie eine Konsolenanwendung, die nicht angezeigt werden ein Konsolen-Fenster.

Es ist möglich bauen eine Konsole app, hinter dessen Fenster sich sehr schnell, aber nicht so schnell, dass es ist, als wenn das Fenster erscheint nie.

Nun, um zu bestimmen, ob eine console-app gestartet wurde vom Entdecker, einige haben vorgeschlagen, zu schauen, die Konsole Ausführung in

(aus mgb ' s Antwort, und KB-Artikel 99115) :

  int left = Console.CursorLeft;
  int top = Console.CursorTop;
  bool ProcessWasRunFromExplorer = (left==0 && top==0);

Diese teilt Ihnen mit, wenn der Prozess gestartet wurde in seine eigene Konsole, aber nicht, ob es war der explorer. Ein Doppelklick im explorer, dies zu tun wäre, aber auch ein Anfang.Prozess() innerhalb einer app würde das gleiche tun.

Wenn Sie möchten, behandeln Sie die Situationen anders, verwenden Sie diese, um zu lernen, den Namen der parent-Prozess:

  System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id);
  string name = Process.GetCurrentProcess().ProcessName ;
  System.Console.WriteLine("Process name: {0}", name);
  PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name);
  Process p = Process.GetProcessById((int)pc.RawValue);
  System.Console.WriteLine("Parent Process id: {0}", p.Id);
  System.Console.WriteLine("Parent Process name: {0}", p.ProcessName);

  //p.ProcessName == "cmd" or "Explorer" etc

Ausblenden der Fenster schnell, nachdem der Prozess gestartet wird, verwenden Sie diese:

  private static readonly int SW_HIDE= 0;

  [System.Runtime.InteropServices.DllImport("user32.dll")]
  private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

  ....
  {
    IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle;
    ShowWindow(myHandle, SW_HIDE);
  }

Wenn Sie produzieren eine winexe (eine WinForms-app) und Anhängen an das übergeordnete Konsole, wenn nötig, auch mit AttachConsole(-1) erhalten Sie nicht das äquivalent einer regelmäßigen console app. Für eine winexe, der übergeordnete Prozess (wie cmd.exe) wird wieder die Eingabeaufforderung sofort nach dem starten einer GUI-Anwendung. In anderen Worten, die Eingabeaufforderung ist aktiv und bereit für Eingaben, während die gerade Vorgestellte Prozess kann emitting output. Das ist verwirrend und wird wahrscheinlich nur nützlich für das Debuggen von winforms-Anwendungen.

Dieser arbeitete für mich.

  • Was möchten Sie es stattdessen tun?
  • Ich will es, unsichtbar zu sein.
  • Der test, um festzustellen, wenn das Programm gestartet wurde, in seine eigene Konsole ist falsch. Eingabe cls & program.exe in der Befehlszeile wird fälschlicherweise Stand, dass das Programm gestartet wurde, in seine eigene Konsole. Sie könnte das gleiche tun, aus einer batch-Datei. Wahrscheinlich gibt es andere Möglichkeiten, um die Niederlage zu testen.
Schreibe einen Kommentar