Ir para conteúdo
Fórum Script Brasil
  • 0

Reabrir programa já em execução [Reaberto]


Douglas Soares

Pergunta

Olá, esse é meu segundo tópico aqui no Script Brasil, fiquei muito contente, pois a agilidade do pessoal daqui do forum é muito boa, pois meu primeiro tópico, foi rapidamente respondido. Vamos lá: :lol:

No DPR do programa eu verifico se o programa já está em execução, aqui vai um trecho do codigo!

Var HprevHist : HWND;
MutexHandle : THandle;

function OneInstanceAndRunning: Boolean;
    begin
        result := false;
            if (MutexHandle <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)
then
            begin
                MessageDlg('O Programa já está em Execução nessa Maquina!', mtWarning,
[mbOK], 0);
                result := true;
            end;
    end;

begin
  MutexHandle := CreateMutex(nil, True, 'Administra');
    if OneInstanceAndRunning then
    begin
        CloseHandle(MutexHandle);
        Halt;
    end;
  try
  Application.Initialize;
  Application.Title := 'Administra';
  frmAbertura := TfrmAbertura.Create(Application); // Cria o form de abertura
  frmAbertura.Show;
  frmAbertura.Update;
  Application.CreateForm(TfrmPrincipal, frmPrincipal);
  Application.CreateForm(TdtmPrincipal, dtmPrincipal);
  frmAbertura.Hide;
  frmAbertura.Free;
  Application.Run;
  finally
        if LongBool(MutexHandle) then CloseHandle(MutexHandle);
    end;

Ele verifica certinho, até me da a mensagem e depois fecha!

Porem quero ir além disso....

Se ele já estiver em execução gostaria de Restaurar a janela dele e passar mais alguns comandos meus.... será que teria um jeito de fazer isso?

Se tiver desde já agradeço...

Obrigado!

Editado por Jonathan Queiroz
Adcionar tag's (Jonathan)
Link para o comentário
Compartilhar em outros sites

16 respostass a esta questão

Posts Recomendados

  • 0

Opa

então brother tem sim, quanto aos comandos vai depender do que você quer fazer...

mas adaptando seu código ao restaurar a janela, ai vai

Var HprevHist : HWND;
MutexHandle : THandle;

function OneInstanceAndRunning: Boolean;
begin
result := false;
if (MutexHandle <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)
then
begin
MessageDlg('O Programa já está em Execução nessa Maquina!', mtWarning,
[mbOK], 0);
result := true;
end;
end;

begin
  MutexHandle := CreateMutex(nil, True, 'Administra');
  if OneInstanceAndRunning then
  begin
    hPrevInst := FindWindow('TFrmPrincipal', nil);
    if hPrevInst <> 0 then
    ShowWindow(hPrevInst, SW_SHOW);
    CloseHandle(MutexHandle);
    Halt;
  end;
  try
    Application.Initialize;
    Application.Title := 'Administra';
    frmAbertura := TfrmAbertura.Create(Application); // Cria o form de abertura
    frmAbertura.Show;
    frmAbertura.Update;
    Application.CreateForm(TfrmPrincipal, frmPrincipal);
    Application.CreateForm(TdtmPrincipal, dtmPrincipal);
    frmAbertura.Hide;
    frmAbertura.Free;
    Application.Run;
  finally
    if LongBool(MutexHandle) then 
    CloseHandle(MutexHandle);
  end;

procura colocar tudo que for código entre as tags Code, abre um colchete e coloca [ code ] e no fim do código fecha [ /code ] mas sem os espaços entre os colchetes...

isso são colchetes?!

troque em FindWindow() o 'TfrmPrincipal' por 'T' + o nome do seu Form exemplo

se ele chama frmBla então seria 'TfrmBla'

se ele chama frmAbertura então seria 'TfrmAbertura' e por ai vai...

detalhe, seu código já tinha uma variavel q não estava sendo usada (hPrevInst: HWND), mas que na verdade era pra fazer isso q você queria rs

abrxx

Editado por Churc
Link para o comentário
Compartilhar em outros sites

  • 0

Ae manin, mt obrigado, tipo, não funcionou porque o meu programa as vezes vai para o tray, no entanto, eu preciso fazer o que você me disse e acrescentar mais esse código, porem não tenho ideia de onde por...

Application.ShowMainForm := True;
FrmPrincipal.TrayIcon1.ShowApp := True;
Application.Restore;
Application.BringToFront;
FrmPrincipal.OcultarJanela1.Visible := True;
FrmPrincipal.MostrarJanela1.Visible := False;

VLW MAIS UMA VEZ

Link para o comentário
Compartilhar em outros sites

  • 0

opa

Nesse caso, o que você precisa fazer é...

--- Global

const
  WM_RESTFROMTRAY = WM_USER + 1015;
--- Unit do Form Principal
...
  private
    { Private declarations }
    procedure OnRestoreFromTray(var Msg: TMessage); message WM_RESTFROMTRAY;
  public
    { Public declarations }
  end;

...

procedure TNomedoForm.OnRestoreFromTray(var Msg: TMessage);
begin
  Application.ShowMainForm := True;
  FrmPrincipal.TrayIcon1.ShowApp := True;
  Application.Restore;
  Application.BringToFront;
  FrmPrincipal.OcultarJanela1.Visible := True;
  FrmPrincipal.MostrarJanela1.Visible := False;
end;
--- Source do Programa (Menu Project > View Source)
em uses declare - Messages;

Var HprevHist : HWND;
MutexHandle : THandle;

function OneInstanceAndRunning: Boolean;
begin
result := false;
if (MutexHandle <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)
then
begin
MessageDlg('O Programa já está em Execução nessa Maquina!', mtWarning,
[mbOK], 0);
result := true;
end;
end;

begin
  MutexHandle := CreateMutex(nil, True, 'Administra');
  if OneInstanceAndRunning then
  begin
    hPrevInst := FindWindow('TFrmPrincipal', nil);
    if hPrevInst <> 0 then
    SendMessage(hPrevInst, WM_RESTFROMTRAY, 0, 0);
    CloseHandle(MutexHandle);
    Halt;
  end;
  try
    Application.Initialize;
    Application.Title := 'Administra';
    frmAbertura := TfrmAbertura.Create(Application); // Cria o form de abertura
    frmAbertura.Show;
    frmAbertura.Update;
    Application.CreateForm(TfrmPrincipal, frmPrincipal);
    Application.CreateForm(TdtmPrincipal, dtmPrincipal);
    frmAbertura.Hide;
    frmAbertura.Free;
    Application.Run;
  finally
    if LongBool(MutexHandle) then 
    CloseHandle(MutexHandle);
  end;

WM_RESTFROMTRAY voce pode inventar o que voce quiser, no caso eu inventei (Rest = Restore, From = do, Tray = lado do relogio) ou seja, sair da area de notificação e voltar hehe

WM_USER é o final das mensagem que o Windows usa, deste valor pra cima voce cria suas próprias mensagens, voce nunca deve usar pra baixo senao da conflito entre o Windows e seu programa, um exemplo, voce manda uma mensagem pro seu programa mas o windows identifica e faz algo ou vice e versa, portanto em mensagens customizadas sempre use WM_USER + algum valor...

O resto é lógica acho que da pra entender sem explicar né rs

no Form principal voce declara a procedure pra receber a Mensagem, e no Source do programa voce envia... quando ela recebe ela faz o que voce quiser que ela faça, no caso como voce já passou o codigo ficou ate mais facil

abraxx

Editado por Churc
Link para o comentário
Compartilhar em outros sites

  • 0

Cara, você é demais sabe tudo, pena q eu não sei nem 1/10 do seu conhecimento ehehehe, Puxa, mesmo com sua explicação detalhada e correta, eu tava sofrendo um pouquinho!, hauhauhaua, eu mudava umas coisas pensando q n tinha nada haver, mas tava certo, então eu revirei mechi, e funcionou!!!!, eu nem sabia q dava pra por o const como global depois das USES, eheheheheh, pro se ver como o cara manja aki, huahuahau, então cara, mt obrigado mais uma vez pela ajuda!!!

Precisando estamos ai!!!!!!!!!!

VLWWWWWWWWWWWWWW :lol: :lol: :lol:

Link para o comentário
Compartilhar em outros sites

  • 0

Olá, Infelizmente tive que reabrir esse tópico rsrs...

A função funciona perfeitamente, só que agora percebi q uma outra função parou porcausa dessa...

Quando eu restaurava um backup no programa, eu reiniciava ele... agora quando vai pra reiniciar fala que já está em execução e não abre o programa mais...

por favor se puderem me ajudar

Link para o comentário
Compartilhar em outros sites

  • 0

então

acredito eu que você não esteja dando um CloseHandle(MutexHandle) ao finalizar o aplicativo ou não está finalizando ele corretamente, ta tipo matando o processo...

de qualquer forma o que você pode fazer é usar Parametros de execução exemplo

No source do programa você adiciona

em uses declare - Messages;

Var 
  HprevHist : HWND;
  MutexHandle : THandle;
  szParams: String = '';

procedure GetParams;
var
  i: Integer;
begin
  for i := 1 to ParamCount do
  if (i = 1) then szParams := ParamStr(i) else
  szParams := szParams + ' ' + ParamStr(i);
end;

function OneInstanceAndRunning: Boolean;
begin
result := false;
if (MutexHandle <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)
then
begin
MessageDlg('O Programa já está em Execução nessa Maquina!', mtWarning,
[mbOK], 0);
result := true;
end;
end;

function fromBackup: Boolean;
begin
  Result := Pos('-backup', LowerCase(szParams)) > 0;
end;

begin
  GetParams;
  
  MutexHandle := CreateMutex(nil, True, 'Administra');
  if OneInstanceAndRunning and not (fromBackup) then
  begin
    hPrevInst := FindWindow('TFrmPrincipal', nil);
    if hPrevInst <> 0 then
    SendMessage(hPrevInst, WM_RESTFROMTRAY, 0, 0);
    CloseHandle(MutexHandle);
    Halt;
  end;
  try
    Application.Initialize;
    Application.Title := 'Administra';
    frmAbertura := TfrmAbertura.Create(Application); // Cria o form de abertura
    frmAbertura.Show;
    frmAbertura.Update;
    Application.CreateForm(TfrmPrincipal, frmPrincipal);
    Application.CreateForm(TdtmPrincipal, dtmPrincipal);
    frmAbertura.Hide;
    frmAbertura.Free;
    Application.Run;
  finally
    if LongBool(MutexHandle) then 
    CloseHandle(MutexHandle);
  end;
Então na hora que você for reiniciar o programa, coloca na linha de comando o "-backup" ex
WinExec(PChar('bla.exe -backup'), SW_SHOWNORMAL);

testa ai e me fala

abrax

Link para o comentário
Compartilhar em outros sites

  • 0

num deu, coloquei esse código que você me passou, e o parametro em vez de backup chamei Reiniciar, mas não deu, o codigo q eu uso para reiniciar o programa é esse:

var
AppName : PChar;

procedure AppRestart;
begin
  AppName := PChar(Application.ExeName);
  ShellExecute(HANDLE_FLAG_INHERIT,'open', AppName, nil, nil, SW_SHOWNORMAL);
  Application.Terminate;
end;

e ai com seu código já no souce eu usei o meu código acima desse jeito:

procedure AppRestart;
begin
  AppName := PChar(Application.ExeName);
  WinExec(PChar(AppName + ' -reiniciar'), SW_SHOWNORMAL);
  Application.Terminate;
end;

ehehe, mas continua o problema, o q eu devo fazer? :blush:

Vlw

Link para o comentário
Compartilhar em outros sites

  • 0

opa

então, mas voce alterou em FromBackup de "-backup" para "-reiniciar" ?

com seu código seria

procedure AppRestart;
begin
AppName := PChar(Application.ExeName);
ShellExecute(HANDLE_FLAG_INHERIT,'open', AppName, PChar('-reiniciar'), nil, SW_SHOWNORMAL);
Application.Terminate;
end;

Link para o comentário
Compartilhar em outros sites

  • 0

Churc, cara, eu te amo :wub: , huahuahua, você sabe tudo meoo, mt obrigado mesmo..........

"Churc" nossa esse cara deve ta querendo alguma coisa!

é, eheheheh eu to mesmo, huahauhua, agora reinicia certinho!. O problema é outro, mas não tão importante. lembra das funções para reabrir se já ta aberto e tals, se tiver no tray ele volta e belezera?, entãoooo, quando ele ta minimizado e eu clico no executavel para tentar abrir denovo, dai o programa é puxado pra frente, até ai ta tudo lindo :blink: , porem quando eu levo o programa para o tray, e entro no executavel... ele não ta restaurando de la..., dai quando eu clico com o botão direito do mouse no trayicon do programa para abrir o popup menu e depois clico fora e vou abrir o executavel... dai bixo restaura do tray certinho :wacko: , uhuhuhuhuu, o q eu posso fazer Mestre? huahuhua

Vlw pela ajuda q já foi dada :rolleyes:

Editado por Douglas_Soares
Link para o comentário
Compartilhar em outros sites

  • 0

Fala brother rs

então, tente dar um ShowWindow primeiro antes do SendMessage

...
if hPrevInst <> 0 then
begin
  ShowWindow(hPrevInst, SW_SHOW);
  SendMessage(hPrevInst, WM_RESTFROMTRAY, 0, 0);
end;
...
ou
...
if hPrevInst <> 0 then
begin
  SendMessage(hPrevInst, WM_SYSCOMMAND, SC_RESTORE, 0);
  SendMessage(hPrevInst, WM_RESTFROMTRAY, 0, 0);
end;
...

testa e me fala ;)

abrxx

Editado por Churc
Link para o comentário
Compartilhar em outros sites

  • 0

então, tentei dos dois métodos e não funcionou. Eu abro o Sistema, e coloco ele no tray, dai eu vou e tento abrir dinovo, ele só da a msg e não restaura... porem quando eu clico com o botao direito no icone do tray para ser exibido o popup menu, dai eu clico fora dele, e vou tentar abrir o sistema dinovo, e ele vai! ehehe!

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

então, testei aqui simulando uma janela no Tray (lado do relogio) escondida e enviando uma mensagem para restaurá-la, restarou normalmente

teste ai e diga se restaura a janela do Tray... abra seu programa, deixe ele escondido no tray, crie outro programa e coloque o código

var
  h: THandle;
begin
  h := FindWindow('TForm1', nil);

  if h <> 0 then
  SendMessage(h, WM_SYSCOMMAND, SC_RESTORE, 0);

troque "TForm1" por T + o nome do seu Form exemplo, se chama frmPrincipal como parece ser coloque "TfrmPrincipal"

coloque o código no clique de um botão e veja se ele restaura a janela

testa ai e me fala

abrx

Link para o comentário
Compartilhar em outros sites

  • 0

:wacko: Nossa, depois de algumas compilações, num é que ficou certinho agora... uhuhu acho q é esse delphi maluco, huahuhaua, mas agora ta certinho cara, mt obrigado, agora na parte da MSG que aparece, "O Programa já está em execução nessa Maquina", quando eu uso o parametro -reiniciar, eu queria que reiniciasse direto, sem eu ter q apertar ok na MSG.

abraços

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...