Delphi: Exemplo utilizando CreateProcess
Já comentei há alguns dias que existem três formas para rodar uma aplicação externa em um programa escrito em Delphi. São elas: ShellExecute, WinExec e CreateProcess.
Ontem precisei executar o MySQL Dump para gerar um backup de uma base de dados. Até aqui nenhum segredo, pois o WinExec faz isso facilmente. No entanto, eu precisava manter a aplicação esperando até que o comando terminasse de executar.
A única forma de fazer isto é utilizando o CreateProcess. Veja a rotina que utilizei:
Para realizar o dump, usei o seguinte comando:
cmd.exe /c “c:\executavel\Utils\mysqldump.exe -hHOST -uUSUARIO -pSENHA -c –add-drop-table teste > C:\teste.sql”
Algumas informações importantes sobre esta rotina:
- O CreateProcess requer vários parâmetros. No entanto, veja que a rotina acima pede um só, portanto ela assume um comportamento padrão;
- Enquanto a aplicação externa está em execução, o programa que criou ela fica esperando (graças ao WaitForSingleObject);
- Como utilizei o cmd.exe para rodar o MySQL Dump, precisei passar o nome do executável e seus parâmetros dentro de ” ” (até descobrir isso passaram-se algumas horas);
- A aplicação criada é executada em modo SW_HIDE, ou seja, escondida.
Fonte: Dicas de Delphi
Não deixe de conferir as sugestões de livros sobre Delphi que eu elaborei. Lá você encontrará informações sobre este e outros comandos.
É isso aí! T+





Olá estou usando o delphi 8 e o compilador não reconhece a função fillchar.
Vc pode me ajudar ?
Opa.
Você deu um uses na unit System?
T+
Funciona no .net?
Talvez com P/Invoke ou algo do gênero
T+
Olá…
será que alguém pode me ajudar?
Tenho uma aplicação que chama outro executável, já utilizei o CreateProcess, o WinExec e o ShellExecute, todos deram certo para chamar o outro executável, no entanto eu gostaria é que se o executável estiver aberto ele restaurar e não abrir um novo.
Utilizei também o seguinte código:
——————————-
TesteExecutável := FindWindow(nil,’Caption do formulário principal’);
if TesteExecutável 0 then
SetForegroundWindow(TesteExecutável)
else
ShellExecute(Handle,’Open’,'Executável’,nil,’diretório’,sw_shownormal);
——————————-
Este código dá certo, acontece que se o executável estiver no form principal funciona tudo certinho, mas se o executável tiver aberto qualquer outra tela(ShowModal) o programa abre a tela principal deixando esta outra tela(ShowModal) atráz fazendo com que o executável trave uma vez que o formulário ativo ficou por tráz do form principal.
Se alguém tiver uma solução para isso ficaria muito grato.
Desde já agradeço.
Caro Marcos,
Cara essa rotina CreateProcess resolveu minha vida
eu usava o winexec com um sleep depois para aguardar mais isso era uma m%$%#$%. Obrigado
Marcos,
Funcionou perfeitamente, utilizei com o mesmo propósito que o seu, só que no meu caso utilizei para o PostgreSQL.
Parabéns, excelente dica.
Gilberto
Pessoal,
essa função (CreateProcess), poderia ser usado em um windows service?
Preciso abrir uma aplicação, mas ela fica escondida, não abre uma janela.
Alguma sugestão???
Ola,
estou trabalhando com o a mesma função porem quando o WaitForSingleObject estra em ação ele para o sistema todo, eu precisaria que pelo menos um form dele continua-se em execução normal.
Existe alguma outra função que não parace o sistema todo … ou q faça algo parecido ?
Obrigado pela atenção
Adios
Enquanto a aplicação externa está em execução, o programa que criou ela fica esperando (graças ao WaitForSingleObject). Tem como deixar as duas funcionando sumultaneamente, pois tirei esse comando e não deu certo.
Me perdoem por comentar um post de 2006, mas só hoje me deparei com a necessidade de usar esta rotina. Funciona perfeitamente meu unico problema é que ela estará dentro de um software que distribuirei entre os funcionarios de uma grande empresa e me pergunto sobre a questao de segurança.
Rodando um analisador de processos do windows, vejo la claramente a senha passada pelo controle.
caso queiram ver com os proprios olhos o link do sistema que estou usando para monitorar estes processos é:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
minha duvida… nao existe a possibilidade de criar o processo… aguardar que ele me solicite outras informações ou até mesmo automatizar isso…
Podendo-se “ler” a saida do console, como por exemplo.. executarmos lá o comando
“cmd.exe /c date”
o console ira aguardar com a seguinte entrada:
“Data atual: sáb 27/09/2008
Digite a nova data: (dd-mm-aa)”
como eu consigo informar estes dados sem a intervenção do usuario ?
a idéia é fornecer os dados de segurança como login e senha depois de executado, e não na linha de comando.
teoricamente, ficaria mais dificil de ser visto essas informaços se passados como um input no console e não diretamente via parametros.
caso alguem consiga resolver isto me dê uma luz. estou procurando esta resposta a dias sem nenhum sucesso ate o presente momento.
deixo aqui meu email para caso uma boa alma apareça…
campsoft@gmail.com
Grato. !
e como chamar o visualizador de imagens do windows ??
como executo o visualisador de imagens do windows atraves do delphi ?
Estou querendo chamar um programa externo dentro de um serviço que criei no delphi.. usando timer,, o serviço fica verificando se o programa externo está aberto, se não estiver ele abre.. e funciona… mas o form não abre… é necessário fazer alguma coisa?
Obrigado
Amigo Marcos, tudo bom?
Tentei realizar esta função, porém não obtive resultado. A função é de 2006 e talvez a IDE de hoje não aceite mais isto. Digo porque estou tentado no Delphi 2009, MySQL 5.0, Windows XP SP2
Quando executo a função com o mesmo comando seu, alterando somente para minhas atribuições, tais como localhost, username, password, banco de dados, etc.
Me resulta este erro: “Acess violation at address 7C82F293 in module ‘kernel32.dll’. Write of address 0053F4E6″.
Poderia me ajudar, como proceder? Nescessito justamente desta função.
Grato.
Estou com o mesmo problema do Lucas Ferreira, meu Delphi tambem é 2.009.
Se alguem tiver uma luz eu agradeço.
Daniel.
Marcos montei esta rotina exatamente igual e ele vai para o prompt mas nao executa o comando veja se eu estou fazendo alguma coisa errada
primeiro eu carrego toda a linha de comando para uma variavel chamada vadditional é esta abaixo ela é grande mesmo por causa dos parametros
vadditional_data := ‘cmd.exe /c C:\Maxtrack\MaxtrackServer\Decode_Additional_Data.exe –d –mtc ‘ + serial + ‘ –if C:\Maxtrack\MaxtrackServer\XMLData\’ + arq_xml.text +
‘ -of C:\Maxtrack\MaxtrackServer\XMLDecode\’ + serial + copy(arq_xml.text,9,10) ;
depois chamo a funcao
Cria_Processo(vadditional_data);
Aqui esta a função como vc demonstra o que ele faz é somente ir ao prompt mas nao executa e nem traz a linha de comando,,se puder me ajudar
Funcao :::
Function TForm1.Cria_Processo(cmd : string) : boolean ;
var
SUInfo : TStartupInfo;
ProcInfo : TProcessInformation;
Begin
FillChar(SUInfo, SizeOf(SUInfo), #0) ;
SUInfo.cb := Sizeof(SUInfo);
SUInfo.dwFlags := STARTF_USESHOWWINDOW;
SUInfo.wShowWindow := SW_HIDE ;
result := createprocess(nil,
pchar(cmd),
nil,
nil,
false,
REALTIME_PRIORITY_CLASS,
nil,
nil,
SUInfo,
ProcInfo) ;
if (result) then
Begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end
End;
Olá.
Não sei se ajuda vocês.
Testei a função e sobre o “travamento” do sistema, resolvi, substituindo a linha :
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
por :
sleep(2000);
onde o “2000″ é o tempo que escolhi para a minha necessidade.
Parabenizo o autor por manter este post até a presente data, pois mesmo ao longo dos 3 anos de existência, este me ajudou muito e é justamente o que buscava a um bom tempo.
Muito grato pela dica.
Abs a todos
Ola Marcos Dell’ Antonio.
Muito bom esse seu post foi a solucao que achei para executar o mysql de um pendrive funcionou certinho com o delphi 2007 mas no delphi 2009 ele consegue instalar como um servico do windows mas quanto eu tento iniciar o mysql ele trava, vc tem alguma ideia de como eu resolvo este problema, ja tentei de varia maneira mas parece q o delphi 2009 tem muitas coisa diferentes das versoes anteriores
CreateProcessSimple(’cmd.exe /c “”‘ + ExtractFilePath(Application.ExeName) + ‘mysql\bin\mysqld.exe” –install mysql_new –defaults-file=”‘ + ExtractFilePath(Application.ExeName) + ‘mysql\my.ini”"‘);
Acima esta o fonte de instalacao do mysql no serviço do windos
CreateProcessSimple(’cmd.exe /c “”net start mysql_new”"‘);
e acima é onde esta dando o problema
Grato Marcos Moreno
Boa Noite, estou tentando usar o createprocess com o delphi2009 mas estou tendo um access violation no Kernel32 (como o lucas Ferreira e o Daniel, alguém tem uma dica ? Thanks
André, para fornecer a senha e login para o processo, sugiro você passá-los como argumentos criptrografados.
Também é possível vc identificar a window que vc abriu pelo processo e setar manualmente lá a senha e login do usuário, ou fazer o inverso também, fazer a window que vc abriu acessar variáveis do teu aplicativo que abriu o processo, mas já é assunto para um outro escopo.
Obrigado!
D+
Olá, Marcos/Todos
Parabén pelo post…
Tenho um serviço criado que roda perfeitamente em XP, tanto com WinExec, ShellXecute ou CreateProcess, ocorre que no VISTA/Delphi 7, o aplicativo que é chamado não executa. Já debuguei o serviço chega até alinha onde é executado o ShellExecute ou WinExec, mas não acontece nada. Alguém pode me ajudar ?
Boa noite, passei aqui para agradecer o Post… me ajudou bastante! Falouuu…
Olá Marcos, vi seu post e achei muito interessante. Utilizo algo parecido, mas quando passo o comando
C:\****\***\ não é reconhecido como um comando interno
ou externo, um programa operável ou um arquivo em lotes.
Desde já agradeço