Kiedy musimy ustawić ProcessStartInfo.UseShellExecute na True?


143
//
// 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; }

Jeśli utworzymy nowy proces, kiedy musimy ustawić UseShellExecute na True?

Odpowiedzi:


213

Właściwość UseShellExecuteboolean jest związana z używaniem funkcji ShellExecute w systemie Windows w porównaniu z funkcją CreateProcess - krótka odpowiedź jest taka, że ​​jeśli UseShellExecutejest prawdziwe, Processklasa będzie korzystać z ShellExecutefunkcji, w przeciwnym razie będzie używać CreateProcess.

ShellExecuteDłuższą odpowiedzią jest to, że funkcja służy do otwierania określonego programu lub pliku - jest mniej więcej równoważna wpisaniu polecenia do wykonania w oknie dialogowym uruchamiania i kliknięciu OK, co oznacza, że ​​można jej użyć do (na przykład):

  • Otwieraj pliki .html lub strony internetowe za pomocą domyślnej przeglądarki bez konieczności znajomości tej przeglądarki,
  • Otwórz dokument Word bez konieczności poznania ścieżki instalacji programu Word
  • Uruchom dowolne polecenie na PATH

Na przykład:

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

Jest bardzo łatwy w użyciu, wszechstronny i potężny, jednak ma kilka wad:

  • Nie jest możliwe przekierowanie standardowych uchwytów wejścia / wyjścia / błędów

  • Prawdopodobnie nie jest możliwe określenie deskryptorów zabezpieczeń (ani innych fajnych rzeczy) dla procesu potomnego

  • Istnieje możliwość wprowadzenia luk w zabezpieczeniach, jeśli przyjmiesz założenia dotyczące tego, co faktycznie zostanie uruchomione:

     // 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();
    

CreateProcessjest znacznie bardziej precyzyjnym sposobem uruchamiania procesu - nie przeszukuje ścieżki i pozwala na przekierowanie między innymi standardowego wejścia lub wyjścia procesu potomnego. Wadą CreateProcessjest jednak to, że żaden z 3 przykładów, które podałem powyżej, nie zadziała (spróbuj i zobacz).

Podsumowując, powinieneś ustawić UseShellExecutena false, jeśli:

  • Chcesz przekierować standardowe wejście / wyjście / błąd (jest to najczęstszy powód)
  • Nie chcesz przeszukiwać ścieżki do pliku wykonywalnego (np. Ze względów bezpieczeństwa)

I odwrotnie, powinieneś zachować UseShellExecuteprawdę, jeśli chcesz otwierać dokumenty, adresy URL lub pliki wsadowe itp., Zamiast jawnie podawać ścieżkę do pliku wykonywalnego.


2
Świetne rzeczy, ale piszesz, że (za pomocą ShellExecute): „To [twierdzisz] nie jest możliwe, aby przekierować standardowe uchwyty wejścia / wyjścia / błędów” <- Z pewnością jest to niepoprawne lub niedokładne. Nawet z useShellExecute ustawionym na true, chociaż rzeczywiście nie możesz tego zrobić processStartInfo.RedirectStandardOutput=true, wydaje mi się, że nadal możesz przekierować standardowe wyjście, wykonując process.Arguments= "cmd /c dir >c:\\crp\\a.a". Podobnie z okna dialogowego uruchamiania, które możesz zrobićcmd /c dir>c:\crp\a.a
barlop

4
mówisz też, że kiedy UseShellExecute=falsenp. CreateProcess, nie sprawdza ścieżki, ale widzę, że nawet gdy robię „UseShellExecute = false”, tj. rzekomo nie sprawdzam ścieżki, to process.FileName = „cmd.exe” działa, więc tak jest sprawdzanie c: \ windows \ system32. A jeśli skopiuję cmd.exe do c: \ windows i nadam mu nazwę cmmmd.exe, to zrobię process1.FileName = "cmmmd.exe", który też działa, więc sprawdza c: \ windows, więc wygląda na to, że sprawdza ścieżkę lub kilka katalogów.
barlop

2
Dokumentacja MSDN zgadza się z @barlop: „Gdy UseShellExecute ma wartość false, właściwość FileName może być pełną ścieżką do pliku wykonywalnego lub prostą nazwą pliku wykonywalnego, którą system spróbuje znaleźć w folderach określonych przez zmienną środowiskową PATH.”
Bob

Ustawiając UseShellExecutena true, mogłem udostępnić zmienną środowiskową (która została utworzona tylko w procesie wywoływania). Bardzo przydatne
Mitkins

14

Myślę głównie o plikach niewykonywalnych. Na przykład, jeśli próbujesz otworzyć .htmlplik, jeśli będziesz musiał ustawić UseShellExecutesię truei otworzy się .htmlw przeglądarce, który jest ustawiony jako domyślny przez użytkownika.


12

Z MSDN :

Ustawienie tej właściwości na false umożliwia przekierowanie strumieni danych wejściowych, wyjściowych i błędów.

UseShellExecute musi mieć wartość false, jeśli właściwość UserName nie ma wartości null lub jest pustym ciągiem, lub InvalidOperationException zostanie zgłoszony po wywołaniu metody Process.Start (ProcessStartInfo).

Kiedy używasz powłoki systemu operacyjnego do uruchamiania procesów, możesz uruchomić dowolny dokument (który jest dowolnym zarejestrowanym typem pliku skojarzonym z plikiem wykonywalnym, który ma domyślną akcję otwarcia) i wykonać operacje na pliku, takie jak drukowanie, za pomocą komponentu Process. Gdy UseShellExecute ma wartość false, można uruchamiać tylko pliki wykonywalne ze składnikiem Process.

UseShellExecute musi mieć wartość true, jeśli ustawisz właściwość ErrorDialog na true.


0

Jeśli chcemy ukryć bieżące okno wykonywalne aplikacji, to UseShellExecute należy ustawić na true


0

Gdy ścieżka zawiera spację lub inne znaki specjalne (np. Z akcentem), CreateProcess (UseShellExecute = false) wydaje się używać krótkich nazw plików (notacja „DOS” 8.3), ShellExecute (UseShellExecute = true) używa długich nazw plików. Więc kiedy używasz UseShellExecute = false, upewnij się, że konwertujesz katalog i nazwy plików na nazwy 8.3 (google „.net jak uzyskać nazwę pliku 8.3”). (Nie jestem do końca pewien, jakie wersje systemu Windows i / lub systemy plików robią to w ten sposób, przetestowano na Windows 7, NTFS.)


Czy to możliwe, że po prostu odcina ścieżkę w przestrzeni? Umieszczenie cudzysłowu wokół „ścieżki / nazwy programu” rozwiązuje ten problem.
gbarry
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.