Wann müssen wir UseShellExecute auf True setzen?


134
//
// Summary:
//     Gets or sets a value indicating whether to use the operating system shell
//     to start the process.
//
// Returns:
//     true to use the shell when starting the process; otherwise, the process is
//     created directly from the executable file. The default is true.
[DefaultValue(true)]
[MonitoringDescription("ProcessUseShellExecute")]
[NotifyParentProperty(true)]
public bool UseShellExecute { get; set; }

Wenn wir einen neuen Prozess erzeugen, wann müssen wir UseShellExecute auf True setzen?

Antworten:


202

Die UseShellExecuteboolesche Eigenschaft bezieht sich auf die Verwendung der Windows- ShellExecute- Funktion im Vergleich zur CreateProcess- Funktion. Die kurze Antwort lautet: Wenn UseShellExecutetrue, wird die ProcessKlasse die ShellExecuteFunktion verwenden, andernfalls wird sie verwendet CreateProcess.

Die längere Antwort lautet, dass die ShellExecuteFunktion zum Öffnen eines bestimmten Programms oder einer bestimmten Datei verwendet wird. Dies entspricht in etwa der Eingabe des auszuführenden Befehls in den Ausführungsdialog und dem Klicken auf OK. Dies bedeutet, dass er beispielsweise verwendet werden kann:

  • Öffnen Sie HTML-Dateien oder das Web mit dem Standardbrowser, ohne wissen zu müssen, um welchen Browser es sich handelt.
  • Öffnen Sie ein Word-Dokument, ohne den Installationspfad für Word kennen zu müssen
  • Führen Sie einen beliebigen Befehl auf dem aus PATH

Beispielsweise:

Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.FileName = "www.google.co.uk";
p.Start();

Es ist sehr einfach zu bedienen, vielseitig und leistungsstark, hat jedoch einige Nachteile:

  • Es ist nicht möglich, die Standard-Eingabe- / Ausgabe- / Fehlerhandles umzuleiten

  • Es ist unmöglich, Sicherheitsbeschreibungen (oder andere coole Dinge) für den untergeordneten Prozess anzugeben

  • Es besteht die Möglichkeit, Sicherheitslücken einzuführen, wenn Sie Annahmen darüber treffen, was tatsächlich ausgeführt wird:

     // If there is an executable called "notepad.exe" somewhere on the path 
     // then this might not do what we expect
     p.StartInfo.FileName = "notepad.exe";
     p.Start();

CreateProcessist eine weitaus präzisere Methode zum Starten eines Prozesses. Sie durchsucht den Pfad nicht und ermöglicht es Ihnen, (unter anderem) die Standardeingabe oder -ausgabe des untergeordneten Prozesses umzuleiten. Der Nachteil von ist CreateProcessjedoch, dass keines der 3 Beispiele, die ich oben gegeben habe, funktioniert (probieren Sie es aus und sehen Sie).

Zusammenfassend sollten Sie UseShellExecutefalse setzen , wenn:

  • Sie möchten die Standardeingabe / -ausgabe / -fehler umleiten (dies ist der häufigste Grund).
  • Sie möchten den Pfad nicht nach der ausführbaren Datei durchsuchen (z. B. aus Sicherheitsgründen).

Umgekehrt sollten Sie UseShellExecutetrue beibehalten , wenn Sie Dokumente, URLs oder Batchdateien usw. öffnen möchten, anstatt den Pfad zu einer ausführbaren Datei explizit angeben zu müssen.


2
Tolles Zeug, aber Sie schreiben (mit ShellExecute): "Es ist nicht möglich, die Standard-Eingabe- / Ausgabe- / Fehlerhandles umzuleiten." <- Das ist sicherlich falsch oder ungenau. Selbst wenn useShellExecute auf true gesetzt ist, können Sie dies zwar nicht tun processStartInfo.RedirectStandardOutput=true, aber es scheint mir, dass Sie die Standardausgabe trotzdem umleiten können, indem Sie dies tun process.Arguments= "cmd /c dir >c:\\crp\\a.a". Ebenso können Sie aus einem Dialogfeld "Ausführen"cmd /c dir>c:\crp\a.a
Barlop

4
Außerdem sagen Sie, dass, wenn z. UseShellExecute=falseB. CreateProcess, der Pfad nicht überprüft wird, aber ich sehe, dass process.FileName = "cmd.exe" auch dann funktioniert, wenn ich "UseShellExecute = false" ausführe, dh angeblich den Pfad nicht überprüfe Überprüfen von c: \ windows \ system32. Und wenn ich cmd.exe nach c: \ windows kopiere und cmmmd.exe nenne, dann mache ich process1.FileName = "cmmmd.exe", das auch funktioniert, also prüft es c: \ windows, also scheint es, als würde es den Pfad überprüfen, oder einige Verzeichnisse.
Barlop

2
MSDN-Dokumente stimmen mit @barlop überein: "Wenn UseShellExecute false ist, kann die FileName-Eigenschaft entweder ein vollständig qualifizierter Pfad zur ausführbaren Datei oder ein einfacher ausführbarer Name sein, den das System in Ordnern zu finden versucht, die in der Umgebungsvariablen PATH angegeben sind."
Bob

Durch die Einstellung UseShellExecuteauf konnte trueich eine Umgebungsvariable freigeben (die nur im aufrufenden Prozess erstellt wurde). Sehr praktisch
Mitkins

14

Ich denke hauptsächlich für nicht ausführbare Dateien. Wenn versuchen , zum Beispiel einer öffnen .htmlDatei, wenn Sie festgelegt haben würden UseShellExecutezu , trueund das wird das Öffnen .htmlin einem Browser, der als Standard vom Benutzer festgelegt wird .


12

Von MSDN :

Wenn Sie diese Eigenschaft auf false setzen, können Sie Eingabe-, Ausgabe- und Fehlerströme umleiten.

UseShellExecute muss false sein, wenn die UserName-Eigenschaft nicht null oder eine leere Zeichenfolge ist. Andernfalls wird beim Aufrufen der Process.Start-Methode (ProcessStartInfo) eine InvalidOperationException ausgelöst.

Wenn Sie die Betriebssystem-Shell zum Starten von Prozessen verwenden, können Sie jedes Dokument (bei dem es sich um einen registrierten Dateityp handelt, der einer ausführbaren Datei mit einer Standardaktion zum Öffnen zugeordnet ist) starten und mit der Prozesskomponente Vorgänge für die Datei ausführen, z. B. Drucken. Wenn UseShellExecute false ist, können Sie nur ausführbare Dateien mit der Process-Komponente starten.

UseShellExecute muss true sein, wenn Sie die ErrorDialog-Eigenschaft auf true setzen.


0

Wenn wir das aktuelle ausführbare Anwendungsfenster ausblenden möchten, sollte UseShellExecute auf true gesetzt werden


0

Wenn der Pfad ein Leerzeichen oder andere Sonderzeichen (dh mit Akzent) enthält, verwendet CreateProcess (UseShellExecute = false) anscheinend kurze Dateinamen (Notation "DOS" 8.3), ShellExecute (UseShellExecute = true) lange Dateinamen. Wenn Sie UseShellExecute = false verwenden, stellen Sie sicher, dass Sie Ihre Verzeichnis- und Dateinamen in 8.3-Namen konvertieren (google ".net, wie man 8.3-Dateinamen erhält"). (Nicht genau sicher, welche Windows-Versionen und / oder Dateisysteme dies auf diese Weise tun, getestet unter Windows 7, NTFS.)


Könnte es sein, dass es nur den Weg im Raum abschneidet? Das Setzen von Anführungszeichen um den "Pfad- / Programmnamen" löst dieses Problem.
Gbarry
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.