Saturday 14 April 2018

Exceção do processo beforeforexit


Exceção waitforexit do processo
Obter através da App Store Leia esta publicação em nosso aplicativo!
Como matar um processo sem obter um "processo" saiu " exceção?
Eu uso Process. Kill () para matar um processo. Como isso:
e às vezes o processo irá sair diretamente entre as linhas, então o controle entrará dentro se Kill for render uma exceção:
Agora, o envolvimento do código em try-catch não parece ser uma boa idéia porque InvalidOperationException pode ser chamado por outros motivos.
Existe uma maneira de matar um processo sem ter uma exceção no cenário descrito?
Você poderia P / Invoke TerminateProcess passando Process. Handle. Em seguida, avalie manualmente a causa dele (GetLastError ()). Qual é aproximadamente o que Process. Kill () faz internamente.
Mas note que o TerminateProcess é assíncrono. Então, você precisaria aguardar o controle do processo para ter certeza de que ele está pronto. Usando Process. Kill () faz isso para o seu.
Atualização: Correção, Process. Kill () também é executado de forma assíncrona. Então, você precisará usar WaitForExit () para aguardar o encerramento completo - se você se importar.
Francamente, eu não incomodaria. É claro que existe sempre a possibilidade (remota?) De que alguma "arbitrária" InvalidOperationException se separe dessa linha de código, que não está relacionada ao processo que não está mais lá ou que o objeto Processo esteja em um estado inválido, mas em realidade eu acho que você pode apenas ir com o try / catch em torno do Kill.
Além disso, dependendo da sua aplicação, você poderia considerar o registro desta matança de qualquer maneira, já que parece uma espécie de medida de último recurso. Nesse caso, registre o InvalidOperationException real com ele. Se as coisas ficam estranhas, você tem, pelo menos, seus logs para verificar por que o Kill falhou.
Tendo tudo o que disse, você também pode querer considerar capturar / manipular o Win32Exception pelas mesmas razões.

Exceção waitforexit do processo
Obter através da App Store Leia esta publicação em nosso aplicativo!
Por que Process. WaitForExit lançaria um & quot; no process & quot; exceção mesmo quando existe um processo?
Eu tenho um serviço do Windows contendo este código:
A finalidade deste código é executar um extrato IFilter em um documento, usamos um processo separado porque alguns IFilters são notoriamente escamosos.
Agora, este código corre perfeitamente bem nas caixas do Windows 7 e do Server 2008 R2, mas em um Windows Server 2003 o WaitForExit imediatamente lança uma exceção "Não há nenhum processo associado a este objeto Processo". O processo existe e completa sua tarefa sem problema.
Alguém viu isso? Alguém pode esclarecer porque o WaitForExit aumentaria esse erro?
Se eu colocar este código em um aplicativo de console e executá-lo também funciona bem na caixa do Windws Server 2003, portanto, parece ser um problema específico ao executar isso em um serviço em uma caixa do Windows Server 2003.
Ao iniciar os processos, com a classe System. Diagnostics. Process, o sistema pode usar a função CreateProcess ou ShellExecuteEx Win32. Ao usar CreateProcess, somente arquivos executáveis ​​podem ser iniciados. Ao usar o ShellExecuteEx, qualquer arquivo que possa ser iniciado usando o comando "Iniciar-> Executar" do shell.
No entanto, estas são formas completamente diferentes de iniciar processos. ShellExecuteEx envolve o shell e pode, por exemplo, reutilizar uma instância existente do Word ou do Excel para abrir um documento, usando as informações armazenadas no HKCR \ & lt; progid & gt; \ shell \ & lt; verb & gt; Chave do registro. Isso pode envolver, por exemplo, usando o DDE para procurar e ativar uma instância do Excel existente.
Consulte a documentação sobre SHELLEXECUTEINFO do ShellExecuteEx:
Observe que ShellExecuteEx pode ou não retornar um hProcess dependendo se um novo processo foi iniciado. Este é o comportamento que você está vendo.
CreateProcess é uma função de nível inferior e cria um processo diretamente, e simplesmente passa os argumentos equivalentes. Sempre retorna um identificador de processo.
Nota: Como você parece estar iniciando um arquivo executável, é um pouco surpreendente que nenhum hProcess seja retornado pelo ShellExecuteEx. No entanto, se você quiser garantir que você obtenha um identificador de processo, usar UseShellExecute = false é a coisa correta a fazer.

Exceção waitforexit do processo
Eu criei um aplicativo de console que inicia outro Exe com a ajuda do método Process. Start (). O que eu quero fazer se no Exe 2 aumentar qualquer exceção, então deve entrar no Exe1. A seguir está o código que escrevi.
static void Main (string [] args)
string arguments = string. Empty;
foreach (string strData em args)
string. Format (& quot ;, arguments, strData);
Processo notePad = novo Processo ();
SecureString secure = new SecureString ();
foreach (char c em & quot; senha & quot;)
ProcessStartInfo startInfo = novo ProcessStartInfo ();
usando (Process exeProcess = Process. Start (startInfo))
string. Format (& quot; - & quot ;, & quot; Exception raised In LaunchModelCatalogueApp: & quot ;, ex. Message), EventLogEntryType. Information);
Programa de classe estática.
static void Main (string [] args)
Se alguma exceção aumentar em Exe 2, então deve ser capturado no Exe 1.Como posso fazer isso?
Obrigado e saudações.
As exceções são uma característica inteiramente intra-processo.
O paradigma padrão é ter o executável retornar um código de retorno do seu método principal. Se retornar 0, ele terminou com sucesso, se retornar qualquer outra coisa, então houve um erro. O número específico retornado pode ser usado para denotar o tipo de erro; Se você não se preocupa em informar diferentes tipos de erros, basta retornar um.
Para fazer isso, altere o método principal para ser int Main, em vez de void Main. Enrole um try / catch em torno de todo o método principal. Na captura, retorne 1, no final da tentativa, retorne 0.
Você pode usar a propriedade ExitCode da classe Process para ler o valor do aplicativo de chamada.
Marcado como Resposta Dummy yoyo Moderator terça-feira, 24 de janeiro de 2012 8:40.
Usando Process. Start para iniciar um novo processo, você não tem como capturar as exceções lançadas em outro processo. Para isso, você precisa de técnicas de Inter Process Communication (IPC). Você pode usar o remoting ou Windows Communication Foundations.
Você pode encontrar muitos artigos na rede sobre como capturar exceção em aplicativos cliente / servidor.
Espero que isso ajude você.
Por favor, marque este post como resposta caso tenha resolvido o seu problema. Programação Feliz!
Proposta como resposta por Sarathi R segunda-feira, 16 de janeiro de 2012 10:43 AM Marcado como resposta por Dummy yoyo Moderador terça-feira, 24 de janeiro de 2012 8:40 AM.
Outra abordagem simples é registrar as exceções em um arquivo de texto e lê-lo onde quiser.
Se esta postagem responder sua pergunta, clique em & quot; Marcar como resposta & quot; . Se esta postagem for útil, clique em & quot; Marcar como Útil & quot; .
Editado por Dummy yoyo Moderador segunda-feira, 16 de janeiro de 2012 8:21 AM Edite o link para disponibilizá-lo. Marcado como Resposta Dummy yoyo Moderator terça-feira, 24 de janeiro de 2012 8:40.
Obrigado Servy, que eu sei sobre o ExitCode e também tenho cansado. mas o problema é que eu não posso retornar a exceção exata com a ajuda de código porque não sei exceção levantada.
Obrigado e saudações.
Você pode usar saída padrão ou fluxo de erro padrão para enviar quantidades maiores de informações. Nesse caso, o erro padrão faria mais sentido. (Você deve usar isso além do código de saída.) Apenas imprima a exceção ao erro padrão no bloco de captura, redirecione os fluxos de saída no programa de chamada e leia o fluxo de erro (ignorando se você receber um código de saída de 0).
Certifique-se de observar as condições de conflito ao ler a saída de um processo, especialmente se estiver lendo de dois fluxos diferentes. A página MSDN no Processo explica algumas armadilhas comuns.
Marcado como Resposta Dummy yoyo Moderator terça-feira, 24 de janeiro de 2012 8:40.
Todas as respostas.
Usando Process. Start para iniciar um novo processo, você não tem como capturar as exceções lançadas em outro processo. Para isso, você precisa de técnicas de Inter Process Communication (IPC). Você pode usar o remoting ou Windows Communication Foundations.
Você pode encontrar muitos artigos na rede sobre como capturar exceção em aplicativos cliente / servidor.
Espero que isso ajude você.
Marque esta postagem como resposta se resolveu seu problema. Programação Feliz!
Proposta como resposta por Sarathi R segunda-feira, 16 de janeiro de 2012 10:43 AM Marcado como resposta por Dummy yoyo Moderador terça-feira, 24 de janeiro de 2012 8:40 AM.
Sim, este é um conceito muito bom. Eu apliquei um dos meus projetos anteriores. Você precisa passar por uma exceção e você deve pegá-la em uma classe derivada de exceção. Eu posso dar um exemplo. você pode verificar o link codeproject / KB / dotnet / unhandledexceptions. aspx.
Lembre-se de clicar em & ldquo; Marcar como resposta & rdquo; na postagem que o ajuda, isso pode ser benéfico para outros membros da comunidade lendo o tópico.
Editado por KashNetDev quinta-feira, 12 de janeiro de 2012 6:26.
Obrigado Adavesh e Kash.
As exceções são uma característica inteiramente intra-processo.
O paradigma padrão é ter o executável retornar um código de retorno do seu método principal. Se ele retornar 0, ele será concluído com sucesso, se ele retornar alguma outra coisa, ocorreu um erro. O número específico retornado pode ser usado para denotar o tipo de erro; Se você não se importar em informar diferentes tipos de erros, basta retornar um.
Para fazer isso, altere o método principal para ser int Main, em vez de void Main. Envolva uma tentativa / captura em torno da totalidade do método principal. Na captura, retornar 1, no final da tentativa, retornar 0.
Você pode usar a propriedade ExitCode da classe Process para ler o valor do aplicativo de chamada.
Marcado como resposta por Dummy yoyo Moderador terça-feira, 24 de janeiro de 2012 8:40 AM.
Obrigado Servy, que eu sei sobre o ExitCode e também tenho cansado. mas o problema é que eu não posso retornar a exceção exata com a ajuda de código porque não sei exceção levantada.
Obrigado e saudações.
Outra abordagem simples é registrar as exceções em um arquivo de texto e lê-lo onde quiser.
Se esta postagem responder sua pergunta, clique em & quot; Marcar como resposta & quot; . Se esta postagem for útil, clique em & quot; Marcar como Útil & quot; .
Editado por Dummy yoyo Moderador segunda-feira, 16 de janeiro de 2012 8:21 AM Edite o link para disponibilizá-lo. Marcado como resposta por Dummy yoyo Moderador terça-feira, 24 de janeiro de 2012 8:40 AM.
Obrigado Servy, que eu sei sobre o ExitCode e também tenho cansado. mas o problema é que eu não posso retornar a exceção exata com a ajuda de código porque não sei exceção levantada.
Obrigado e saudações.
Você pode usar saída padrão ou fluxo de erro padrão para enviar quantidades maiores de informações. Nesse caso, o erro padrão faria mais sentido. (Você deve usar isso além do código de saída.) Apenas imprima a exceção ao erro padrão no bloco de captura, redirecione os fluxos de saída no programa de chamada e leia o fluxo de erro (ignorando se você receber um código de saída de 0).
Certifique-se de observar as condições de conflito ao ler a saída de um processo, especialmente se estiver lendo de dois fluxos diferentes. A página MSDN no Processo explica algumas armadilhas comuns.
Marcado como Resposta Dummy yoyo Moderator terça-feira, 24 de janeiro de 2012 8:40.
A Microsoft está conduzindo uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn.

Exemplo de uso.
Resolvi assim:
Eu redirecionava a entrada, a saída e o erro e administrai a leitura dos fluxos de saída e erro. Esta solução funciona para o SDK 7- 8.1, tanto para o Windows 7 como para o Windows 8.
Eu tentei fazer uma aula que resolva seu problema usando a leitura de fluxo assíncrono, levando em conta Mark Byers, Rob, Stevejay responde. Ao fazê-lo, percebi que existe um erro relacionado à leitura assíncrona do fluxo de saída do processo.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não começou.
Então, você deve iniciar a saída assíncrona lida após o processo ser iniciado:
Fazendo isso, faça uma condição de corrida porque o fluxo de saída pode receber dados antes de configurá-lo como assíncrono:
Então algumas pessoas podem dizer que você só precisa ler o fluxo antes de configurá-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e configurará o fluxo em modo assíncrono.
Não há como conseguir uma leitura assíncrona segura de um fluxo de saída de um processo na forma real "Processo" e "ProcessStartInfo" foi projetado.
Você provavelmente está melhor usando a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que você pode perder algumas informações devido à condição de corrida.
Nenhuma das respostas acima está fazendo o trabalho.
A solução Rob trava e a solução 'Mark Byers' obtém a exceção descarta. (Eu tentei as "soluções" das outras respostas).
Então eu decidi sugerir outra solução:
Este código é depurado e funciona perfeitamente.
Introdução.
A resposta atualmente aceita não funciona (lança exceção) e há muitas soluções alternativas, mas nenhum código completo. Isso é, obviamente, desperdiçando muito tempo das pessoas porque esta é uma questão popular.
Combinando a resposta de Mark Byers e a resposta de Karol Tyl, escrevi um código completo baseado em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos git. É assim que eu usei isso:
Em teoria, você também pode combinar stdout e stderr, mas não testei isso.
As outras soluções (incluindo o EM0) ainda estão bloqueadas para o meu aplicativo, devido a tempos de espera internos e ao uso de StandardOutput e StandardError pela aplicação gerada. Aqui está o que funcionou para mim:
Editar: inicialização adicionada de StartInfo para codificar a amostra.
Este post talvez esteja desactualizado, mas descobri a principal causa por que normalmente ele trava é devido ao excesso de pilha para o redirectStandardoutput ou se você tem redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de espera, pois ele ainda está processando por tempo indefinido.
para resolver esse problema:
Eu acho que isso é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas a razão era diferente. No entanto, isso aconteceria no Windows 8, mas não no Windows 7. A seguinte linha parece ter causado o problema.
A solução era NÃO desativar UseShellExecute. Agora recebi uma janela popup do Shell, que é indesejável, mas muito melhor do que o programa esperando que nada de particular aconteça. Então eu adicionei o seguinte trabalho para isso:
Agora, o único problema que me incomoda é o porquê isso está acontecendo no Windows 8, em primeiro lugar.
Eu sei que isso é velho, mas, depois de ler toda essa página, nenhuma das soluções estava funcionando para mim, embora eu não tentei Muhammad Rehan porque o código era um pouco difícil de seguir, embora eu acho que ele estava no caminho certo . Quando eu digo que não funcionou, isso não é inteiramente verdade, às vezes funcionaria bem, acho que é algo a ver com a duração da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim era usar diferentes threads para ler o StandardOutput e StandardError e escrever as mensagens.
Espero que isso ajude alguém, que pensou que isso poderia ser tão difícil!
Depois de ler todos os posts aqui, resolvi a solução consolidada de Marko Avlijaš. No entanto, não resolveu todos os meus problemas.
Em nosso ambiente, temos um Serviço do Windows que está programado para executar centenas de diferentes. bat. cmd. exe. etc arquivos que se acumularam ao longo dos anos e foram escritas por muitas pessoas diferentes e em diferentes estilos. Não temos controle sobre a redação dos programas e programas; scripts, somos apenas responsáveis ​​pelo agendamento, execução e relatórios sobre o sucesso / falha.
Então eu tentei praticamente todas as sugestões aqui com diferentes níveis de sucesso. A resposta de Marko foi quase perfeita, mas quando executado como um serviço, ele nem sempre captou stdout. Nunca cheguei ao fundo do porquê não.

Exceção do processo beforeforex
System. Diagnostics. Process SetupGUIProcess = novo System. Diagnostics. Process ();
SetupGUIProcess. StartInfo = novo System. Diagnostics. ProcessStartInfo (strStartMenuPath + & quot; \\ Programas \\ AXYZ International \\ A2MC Setup. appref-ms & quot;);
Quando o programa chega à linha WaitForExit, ele causa uma exceção "Nenhum processo está associado a este objeto". O processo começa ok. Estou tentando obter o segmento de chamada para bloquear até que o processo seja encerrado. Esse é o caminho certo?
2. Aguarde até que o aplicativo termine de instalar usando Process. WaitOne.
3. Inicie o Executeable como outro Processo (// exe) instalado recentemente.
4. WaitForProcess (); (// processo do Executeable Name).
Marcado como resposta por Bin-ze Zhao segunda-feira, 05 de outubro de 2009 8:16.
Todas as respostas.
Eu sei com certeza que o processo ainda está sendo executado no momento em que WaitForExit é chamado. Eu percebi que estou iniciando o processo por meio de uma referência clickonce. Eu tentei isso em todas as diferentes maneiras pelas quais você pode iniciar um processo e ocorre a mesma exceção. Se eu começar o processo apenas passando o caminho para iniciar (). o começo retorna nulo. Existe outra maneira de iniciar um aplicativo que é instalado por um escudo de instalação clickonce outro que por referência? Eu estaria interessado em ver se eu poderia chamar o exe diretamente. Talvez então a função WaitForExit conheça o objeto do processo. Isso é intrigante. Obrigado pela resposta.
Os aplicativos ClickOnce são lançados usando uma URL para o arquivo de manifesto de implantação (.application). Então você usa a sintaxe do parâmetro querystring da web:
Eu não tenho um servidor. Eu só quero enviar pessoas 2 instalando sheilds zipped up. Eles os instalam. e um dos programas instalados pode chamar o outro como um processo e depois bloquear e aguardar até que seja feito. Ainda não está claro para mim o que eu tenho que fazer para que eu possa chamar o programa usando a sintaxe acima. Preciso de um sever para fazer isso? Quando você diz, pare de usar o ClickOnce. Você quer dizer parar de chamá-lo por sua referência ou quer dizer parar de usá-lo e usar algum outro método de reprodução? Eu acho que realmente não entendo o que o Click Once significa. O termo Click Once simplesmente encapsula o significado de todas as blindagens de instalação por meio da opção de publicação no Visual Studio? Espero que você veja com o que estou lutando. Tem que haver algo simples aqui, estou faltando.
Eu concordo totalmente com o NoBugz (que muito provavelmente entende isso melhor do que eu). Então, vamos pensar sobre isso você e eu. Quando você visita uma URL, você não inicia um processo ao vivo. Você solicita ao servidor alguns dados e retorna alguns dados e, em seguida, seu fora de sua vida. Não existe um estado persistente como um processo ao qual você pode acessar. Você está tentando usar um aplicativo ClickOnce que usa um URL, então, claro, não há nenhum processo devido exatamente ao que acabei de passar. Pare de usar o ClickOnce.
Crie um aplicativo instalável como esse.
Ligue assim.
Espere por isso assim.
Não concordo que as postagens estão se desviando da sua pergunta. Seu exemplo usa ClickOnce, o único problema que sua experiência é devido ao fato de você estar usando o ClickOnce. É por isso que as pessoas dizem. "pare de usar o ClickOnce". Talvez você não entenda o que o ClickOnce é vs um executável? Este é um exemplo muito simples de exatamente o que você está tentando fazer sem um clique.
Mais uma vez obrigado pela resposta.
1. O clique é uma referência que faz referência a um exe? Gostaria de chamar o exe. Eu simplesmente não consigo encontrar em qualquer lugar no sistema que foi iniciado. Existe um caminho específico onde é colocado quando um clique de publicação clique em um escudo de instalação é executado?
Mais uma vez obrigado pela resposta.
1. O clique é uma referência que faz referência a um exe? Gostaria de chamar o exe. Eu simplesmente não consigo encontrar em qualquer lugar no sistema que foi iniciado. Existe um caminho específico onde é colocado quando um clique de publicação clique em um escudo de instalação é executado?
Há um problema lógico com suas perguntas.
Se você precisa instalar o pacote, você não possui o código-fonte (é por isso que eu assumiria que você continuasse tentando usar um clique), então você está essencialmente morto na água com seus requisitos. Nenhuma fonte = falha épica.
Desculpe, homem, não entendi. Vamos passo passo a passo.
1. Vamos assumir que você sabia onde estava o exe. Você o lançou com um processo. De acordo com o número 2, existem dependências, portanto, seu programa explode. Como você conserta isso? Você precisa instalar o programa antes de tentar executar o exe.
Suponhamos que não sei onde o exe é (porque eu não) porque não parece haver um depois de instalar o botão uma vez instalado o escudo. Se houver outra maneira de criar uma estrutura de instalação para que eu tenha acesso a uma exe. Você pode fornecer o link para a documentação que mostra como fazê-lo?
Eu tenho o arquivo de solução do programa original para o visual studio desde que eu sou o autor. Se eu criei um pacote de instalação do MSI e o descarte como um arquivo MSI, como você diz, então eu poderei chamar o exe up como processo? Onde será localizado? Você pode fornecer o link para a documentação sobre como criar o MSI se ele for instalado um exe?
Se você precisa instalar o pacote, você não possui o código-fonte (é por isso que eu assumiria que você continuasse tentando usar um clique), então você está essencialmente morto na água com seus requisitos. Nenhuma fonte = falha épica.
2. Aguarde até que o aplicativo termine de instalar usando Process. WaitOne.
3. Inicie o Executeable como outro Processo (// exe) instalado recentemente.
4. WaitForProcess (); (// processo do Executeable Name).
Marcado como resposta por Bin-ze Zhao segunda-feira, 05 de outubro de 2009 8:16.
A Microsoft está conduzindo uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn.

Process. WaitForExit () retorna exceção de referência nula.
Quando eu recupero jpg e outros arquivos de imagem do banco de dados (também alguns mp3 que abrem com winamp - que é configurado como o aplicativo padrão) parece que ele retorna um valor nulo, fazendo com que uma Exceção de Referência Nula seja acionada e o programa falhará (Graças a Deus pelo Try-Catch!). Eu mencionei por algum tempo e descobri que o processo que se chama é o dllhost. exe.
Ainda retorna nulo. Agora, se eu alterar o aplicativo padrão que um arquivo está usando para abri-lo, ele funciona bem.
O problema é que não quero alterar as aplicações padrão, uma vez que o aplicativo que estou desenvolvendo será instalado em vários PC diferentes, com diferentes usuários e preferências diferentes.
Abaixo está o código que eu uso para recuperar e abrir os arquivos.
Estou um pouco perdido aqui e eu realmente poderia usar sua ajuda.
Sinta-se à vontade para solicitar quaisquer detalhes que possam ajudar.
Agradeço antecipadamente.
Facebook Twitter LinkedIn experts-exchange / questions / 27883967 / Process-WaitForExit-returns-null-reference-exception. html copy.
Quem está participando?
Líderes da indústria: queremos sua opinião!
Nós valorizamos o seu feedback.
Yeti Cooler, Amazon eGift Card e Movie eGift Card!
existe o problema porque o valor de Process () é nulo. ele lança uma exceção de referência nula.
porque "myProcess" está vazio (nada, nulo)
quanto ao atraso. como eu posso fazer isso ?
Agradeço antecipadamente.
para atrasar durante 0,5 segundos a execução. Nas imagens funciona bem, também desde que o fiel é carregado na memória, o aplicativo exclui o arquivo temporário do disco rígido. O único problema agora é os arquivos mp3 que abrem com o Winamp como o aplicativo padrão. Desde a transmissão, o arquivo não pode ser excluído. Vou precisar descobrir um trabalho para isso (a menos que outro jogador seja usado).
Como dito anteriormente, como codificar o Windows Photo Viewer no meu aplicativo (para incorporá-lo)?
já é um membro? Entrar.
Do novato ao técnico pro & mdash; comece a aprender hoje.
Membros Premium podem se inscrever neste curso sem custo adicional.
Membros Premium podem se inscrever neste curso sem custo adicional.

No comments:

Post a Comment