Estou tentando executar um arquivo em lotes em c #, mas não estou tendo sorte em fazê-lo.
Encontrei vários exemplos na Internet, mas não está funcionando para mim.
public void ExecuteCommand(string command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
}
A cadeia de comandos contém o nome do arquivo em lotes (armazenado em system32
) e alguns arquivos que devem ser manipulados. (Exemplo:) txtmanipulator file1.txt file2.txt file3.txt
. Quando executo o arquivo em lotes manualmente, ele funciona corretamente.
Ao executar o código, isso me dá uma **ExitCode: 1** (Catch all for general errors)
O que estou fazendo de errado?
c#
batch-file
process
processstartinfo
Wessel T.
fonte
fonte
command
é. Se ele contiver caminhos com espaços, você precisará colocar aspas em torno deles.Respostas:
Isso deve funcionar. Você pode tentar despejar o conteúdo dos fluxos de saída e erro para descobrir o que está acontecendo:
* EDIT *
Dadas as informações extras em seu comentário abaixo, consegui recriar o problema. Parece haver alguma configuração de segurança que resulta nesse comportamento (não a investigamos em detalhes).
Isso faz trabalho se o arquivo de lote não está localizado em
C:\Windows\System32
. Tente movê-lo para outro local, por exemplo, o local do seu executável. Observe que manter os arquivos em lotes personalizados ou executáveis no diretório do Windows é uma prática recomendada de qualquer maneira.* EDIT 2 * Ele gira para fora que, se os fluxos são lidos de forma síncrona, um impasse pode ocorrer, quer através da leitura de forma síncrona antes
WaitForExit
ou lendo tantostderr
estdout
de forma síncrona um após o outro.Isso não deve acontecer se você usar os métodos de leitura assíncrona, como no exemplo a seguir:
fonte
essa linha simples executará o arquivo em lotes.
fonte
Depois de uma grande ajuda da steinar, foi isso que funcionou para mim:
fonte
~%dp0
. Adicionando oProcessInfo.WorkingDirectory
fixo.command
se você está chamando o arquivo BAT diretamente?command
parâmetros possam ser usados para enviar argumentos para o arquivo BAT, não é isso que o código aqui mostra. Na verdade, não é usado. E se fosse, provavelmente deveria ser nomeadoarguments
.command
é usado nanew ProcessStartInfo
chamada.Funciona bem. Eu testei assim:
Eu comentei desligar a janela para que eu pudesse vê-lo funcionar.
fonte
Aqui está um exemplo de código c # que está enviando 2 parâmetros para um arquivo bat / cmd para responder a esta pergunta .
Comentário: como posso passar parâmetros e ler um resultado da execução de comandos?
/ de @Janatbek Sharsheyev
fonte
O código abaixo funcionou bem para mim
fonte
fonte
Você já tentou iniciá-lo como administrador? Inicie o Visual Studio como administrador, se você o usar, porque trabalhar com
.bat
arquivos requer esses privilégios.fonte
Eu queria algo que fosse mais diretamente utilizável, sem valores de string codificados específicos da organização. Ofereço o seguinte como um pedaço de código diretamente reutilizável. A menor desvantagem é a necessidade de determinar e passar a pasta de trabalho ao fazer a chamada.
Chamado assim:
Neste exemplo, no Visual Studio 2017, como parte de uma execução de teste, desejo executar um arquivo em lotes de redefinição do ambiente antes de executar alguns testes. (SpecFlow + xUnit). Eu me cansei de etapas extras para executar manualmente o arquivo bat separadamente e queria apenas executá-lo como parte do código de configuração do teste C #. O arquivo em lote de redefinição do ambiente move os arquivos de caso de teste de volta para a pasta de entrada, limpa as pastas de saída etc. para obter o estado inicial de teste adequado para o teste. O método QuotesAround simplesmente coloca aspas na linha de comando, caso haja espaços nos nomes das pastas ("Arquivos de Programas", alguém?). Tudo o que há nele é: string privada QuotesAround (entrada de string) {return "\" "+ input +" \ "";}
Espero que alguns achem isso útil e economize alguns minutos se o seu cenário for semelhante ao meu.
fonte
Com as soluções propostas anteriormente, lutei para obter vários comandos npm executados em loop e obter todas as saídas na janela do console.
Finalmente, começou a funcionar depois que eu combinei tudo dos comentários anteriores, mas reorganizei o fluxo de execução do código.
O que notei é que a assinatura do evento foi feita tarde demais (após o processo já ter sido iniciado) e, portanto, algumas saídas não foram capturadas.
O código abaixo agora faz o seguinte:
O código foi testado contra os deadlocks, embora seja síncrono (uma execução de processo por vez), portanto não posso garantir o que aconteceria se isso fosse executado em paralelo.
fonte
Usando o CliWrap :
fonte
System.Diagnostics.Process.Start(BatchFileName, Parameters);
Eu sei que isso funcionará para arquivos e parâmetros em lote, mas nenhuma idéia de como obter os resultados em c #. Geralmente, as saídas são definidas no arquivo em lotes.
fonte