Quando precisamos definir UseShellExecute como True?


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

Se gerarmos um novo processo, quando precisaremos definir UseShellExecute como True?

Respostas:


202

A UseShellExecutepropriedade booleana está relacionada ao uso da função ShellExecute do Windows versus a função CreateProcess - a resposta curta é que, se UseShellExecutefor verdadeira, a Processclasse usará a ShellExecutefunção, caso contrário, ela a usará CreateProcess.

A resposta mais longa é que a ShellExecutefunção é usada para abrir um programa ou arquivo especificado - é praticamente equivalente a digitar o comando a ser executado na caixa de diálogo de execução e clicar em OK, o que significa que pode ser usado (por exemplo):

  • Abra arquivos .html ou web usando o navegador padrão sem precisar saber o que é esse navegador,
  • Abra um documento do Word sem precisar saber qual é o caminho de instalação do Word
  • Execute qualquer comando no PATH

Por exemplo:

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

É muito fácil de usar, versátil e poderoso, porém vem com algumas desvantagens:

  • Não é possível redirecionar os identificadores padrão de entrada / saída / erro

  • Não é possível especificar descritores de segurança (ou outras coisas interessantes) para o processo filho

  • Existe a possibilidade de introduzir vulnerabilidades de segurança se você fizer suposições sobre o que realmente será executado:

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

CreateProcessé uma maneira muito mais precisa de iniciar um processo - não pesquisa o caminho e permite redirecionar a entrada ou saída padrão do processo filho (entre outras coisas). A desvantagem, CreateProcessporém, é que nenhum dos três exemplos que dei acima funcionará (tente e veja).

Em resumo, você deve definir UseShellExecutecomo false se:

  • Você deseja redirecionar a entrada / saída / erro padrão (esse é o motivo mais comum)
  • Você não deseja procurar o caminho pelo executável (por exemplo, por razões de segurança)

Por outro lado, você deve manter- UseShellExecutese verdadeiro se desejar abrir documentos, URLs ou arquivos em lotes, etc ... em vez de precisar explicitamente dar o caminho para um executável.


2
Ótimas coisas, mas você escreve isso (com ShellExecute): "Não é possível redirecionar os identificadores padrão de entrada / saída / erro" <- Certamente isso é incorreto ou impreciso. Mesmo com useShellExecute definido como true, embora de fato você não possa fazer processStartInfo.RedirectStandardOutput=true, parece-me que você ainda pode redirecionar a saída padrão fazendo isso process.Arguments= "cmd /c dir >c:\\crp\\a.a". Da mesma forma a partir de uma caixa de diálogo Executar você pode fazercmd /c dir>c:\crp\a.a
— barlop

4
Além disso, você diz que quando UseShellExecute=false, por exemplo, CreateProcess, não verifica o caminho, mas vejo que mesmo quando eu faço "UseShellExecute = false", ou seja, supostamente não está verificando o caminho, então process.FileName = "cmd.exe" funciona, portanto verificando c: \ windows \ system32. E se eu copiar o cmd.exe para c: \ windows e nomeá-lo como cmmmd.exe, eu process1.FileName = "cmmmd.exe" que também funciona e, portanto, está verificando c: \ windows para que pareça que está verificando o caminho ou alguns diretórios.
— barlop

2
Os documentos do MSDN concordam com @barlop: "Quando UseShellExecute é false, a propriedade FileName pode ser um caminho completo para o executável ou um nome simples de executável que o sistema tentará encontrar nas pastas especificadas pela variável de ambiente PATH."
— Bob

Ao definir UseShellExecutecomo, trueeu era capaz de compartilhar uma variável de ambiente (que foi criada apenas no processo de chamada). Muito útil
— Mitkins

14

Eu acho principalmente para não executáveis. Por exemplo, se você estiver tentando abrir um .htmlarquivo, será necessário definir UseShellExecutecomo truee isso abrirá o .htmlem um navegador definido como padrão pelo usuário.


12

Do MSDN :

Definir essa propriedade como false permite redirecionar fluxos de entrada, saída e erro.

UseShellExecute deve ser false se a propriedade UserName não for nula ou uma cadeia vazia, ou uma InvalidOperationException será lançada quando o método Process.Start (ProcessStartInfo) for chamado.

Ao usar o shell do sistema operacional para iniciar processos, você pode iniciar qualquer documento (que seja qualquer tipo de arquivo registrado associado a um executável que tenha uma ação de abertura padrão) e executar operações no arquivo, como impressão, com o componente Process. Quando UseShellExecute é false, você pode iniciar apenas executáveis ​​com o componente Process.

UseShellExecute deve ser verdadeiro se você definir a propriedade ErrorDialog como true.


0

Se queremos ocultar a janela executável do aplicativo atual, o UseShellExecute deve ser definido como true


0

Quando o caminho contém um espaço ou outros caracteres especiais (ou seja, acentuados), o CreateProcess (UseShellExecute = false) parece estar usando nomes curtos de arquivos (notação "DOS" 8.3), o ShellExecute (UseShellExecute = true) usa nomes longos de arquivos. Portanto, ao usar UseShellExecute = false, converta os nomes de diretório e arquivo em nomes 8.3 (google ".net como obter o nome do arquivo 8.3"). (Não sabe exatamente quais versões do Windows e / ou sistemas de arquivos fazem dessa maneira, testados no Windows 7, NTFS.)


Será que está apenas cortando o caminho no espaço? Colocar aspas em torno do "nome do caminho / programa" resolve isso.
— gbarry 27/06/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.