Quand devons-nous définir UseShellExecute sur True?


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

Si nous engendrons un nouveau processus, quand devons-nous définir UseShellExecute sur True?

Réponses:


203

La UseShellExecutepropriété booléenne est liée à l'utilisation de la fonction Windows ShellExecute par rapport à la fonction CreateProcess - la réponse courte est que si UseShellExecuteest vrai, la Processclasse utilisera la ShellExecutefonction, sinon elle l'utilisera CreateProcess.

La réponse la plus longue est que la ShellExecutefonction est utilisée pour ouvrir un programme ou un fichier spécifié - cela équivaut à peu près à taper la commande à exécuter dans la boîte de dialogue d'exécution et à cliquer sur OK, ce qui signifie qu'elle peut être utilisée pour (par exemple):

  • Ouvrez des fichiers .html ou Web en utilisant le navigateur par défaut sans avoir besoin de savoir ce qu'est ce navigateur,
  • Ouvrez un document Word sans avoir besoin de savoir quel est le chemin d'installation de Word
  • Exécutez n'importe quelle commande sur le PATH

Par exemple:

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

Il est très facile à utiliser, polyvalent et puissant mais présente quelques inconvénients:

  • Il n'est pas possible de rediriger les poignées d'entrée / sortie / erreur standard

  • Il n'est pas possible de spécifier des descripteurs de sécurité (ou d'autres choses intéressantes) pour le processus enfant

  • Il existe un potentiel d'introduction de vulnérabilités de sécurité si vous faites des hypothèses sur ce qui sera réellement exécuté:

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

CreateProcessest une manière beaucoup plus précise de démarrer un processus - il ne recherche pas le chemin et vous permet de rediriger l'entrée ou la sortie standard du processus enfant (entre autres). L'inconvénient CreateProcessest cependant qu'aucun des 3 exemples que j'ai donnés ci-dessus ne fonctionnera (essayez-le et voyez).

En résumé, vous devez définir UseShellExecutesur false si:

  • Vous souhaitez rediriger l'entrée / sortie / erreur standard (c'est la raison la plus courante)
  • Vous ne souhaitez pas rechercher le chemin de l'exécutable (par exemple pour des raisons de sécurité)

Inversement, vous devez garder UseShellExecutetrue si vous souhaitez ouvrir des documents, des URL ou des fichiers batch, etc. plutôt que d'avoir à donner explicitement le chemin d'un exécutable.


2
Great Stuff, mais vous écrivez que (avec ShellExecute), "Il [vous prétendez] n'est pas possible de rediriger les poignées d'entrée / sortie / erreur standard" <- C'est sûrement incorrect ou inexact. Même avec useShellExecute défini sur true, même si vous ne pouvez pas le faire processStartInfo.RedirectStandardOutput=true, il me semble que vous pouvez toujours rediriger la sortie standard en faisant process.Arguments= "cmd /c dir >c:\\crp\\a.a". De même à partir d'une boîte de dialogue d'exécution, vous pouvez le fairecmd /c dir>c:\crp\a.a
barlop

4
aussi, vous dites que lorsque UseShellExecute=falsec'est- à- dire CreateProcess, ne vérifie pas le chemin, mais je vois que même lorsque je fais "UseShellExecute = false" c'est-à-dire ne vérifiant pas le chemin, alors process.FileName = "cmd.exe" fonctionne donc c'est vérification de c: \ windows \ system32. Et si je copie cmd.exe dans c: \ windows et le nomme cmmmd.exe, alors je fais process1.FileName = "cmmmd.exe" qui fonctionne aussi donc il vérifie c: \ windows donc il semble qu'il vérifie le chemin, ou un tas de répertoires.
barlop

2
Les documents MSDN sont d'accord avec @barlop: «Lorsque UseShellExecute a la valeur false, la propriété FileName peut être un chemin d'accès complet à l'exécutable ou un simple nom d'exécutable que le système tentera de trouver dans les dossiers spécifiés par la variable d'environnement PATH.»
Bob

En définissant UseShellExecutesur, truej'ai pu partager une variable d'environnement (qui n'a été créée que lors du processus d'appel). Très pratique
Mitkins

14

Je pense surtout aux non-exécutables. Par exemple, si vous essayez d'ouvrir un .htmlfichier, si vous devez définir UseShellExecutesur trueet cela ouvrira le .htmldans un navigateur défini par défaut par l'utilisateur.


12

Depuis MSDN :

La définition de cette propriété sur false vous permet de rediriger les flux d'entrée, de sortie et d'erreur.

UseShellExecute doit être false si la propriété UserName n'est pas null ou une chaîne vide, ou une InvalidOperationException sera levée lorsque la méthode Process.Start (ProcessStartInfo) est appelée.

Lorsque vous utilisez le shell du système d'exploitation pour démarrer des processus, vous pouvez démarrer n'importe quel document (qui est tout type de fichier enregistré associé à un exécutable ayant une action d'ouverture par défaut) et effectuer des opérations sur le fichier, telles que l'impression, avec le composant Processus. Lorsque UseShellExecute a la valeur false, vous ne pouvez démarrer que les exécutables avec le composant Process.

UseShellExecute doit être true si vous définissez la propriété ErrorDialog sur true.


0

Si nous voulons masquer la fenêtre exécutable de l'application actuelle, UseShellExecute doit être défini sur true


0

Lorsque le chemin contient un espace ou d'autres caractères spéciaux (c'est-à-dire accentués), CreateProcess (UseShellExecute = false) semble utiliser des noms de fichiers courts (notation "DOS" 8.3), ShellExecute (UseShellExecute = true) utilise des noms de fichiers longs. Ainsi, lorsque vous utilisez UseShellExecute = false, assurez-vous de convertir vos noms de répertoire et de fichier en noms 8.3 (google ".net comment obtenir un nom de fichier 8.3"). (Je ne sais pas exactement quelles versions de Windows et / ou quels systèmes de fichiers le font de cette façon, testé sur Windows 7, NTFS.)


Serait-ce que cela coupe simplement le chemin dans l'espace? Mettre des guillemets autour du "chemin / nom du programme" résout ce problème.
gbarry
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.