03
Jul 08
::
articles :: by Gilberto Saraiva
Folks,
This code below implement a singleton structure for the aplication, and that need to be implemented on the DPR file of the project:
| 01 | uses Windows; |
| 02 | |
| 03 | function AppSingleton(ACheckPath: boolean = false): boolean; |
| 04 | var |
| 05 | s: string; |
| 06 | i, iLast: Cardinal; |
| 07 | begin |
| 08 | s := ParamStr(0); |
| 09 | iLast := 1; |
| 10 | case Integer(ACheckPath) of |
| 11 | 0: for i := 1 to Length(s) do if s[i] = '\' then iLast := i; |
| 12 | 1: for i := 1 to Length(s) do if s[i] in [':','\','.',' '] then s[i] := '_'; |
| 13 | end; |
| 14 | Result := (CreateMutex(nil, true, PChar(Cardinal(@s) + (iLast - 1))) <> 0) and |
| 15 | (GetLastError = 0); |
| 16 | end; |
I use the CreateMutex API that works as a semaphore, if open, the application is unique, if closed the application is already running.
I wrote a condition to check the full path of the application for the Mutex call, so if you want to check the full path use the funciotn with param as True, the default is False and the check will be only on the application exe name.
A little detail about checking the functionality of this function:
Under debug mode the checkout on full path mode will fail and more then one application can be raised. This problem is because the relationship of the application with other program, so the CreateMutex API understand the Process ID is diferent from others.
articles — No comments
19
May 08
::
articles :: by Gilberto Saraiva
Camaradas,
O CreateMutex é uma função disponibilizada pela plataforma Windows ( API ) que cria uma sinalização a nível de processo na Kernel32, ou seja, você poderá criar uma sinalização mutex que lhe servirá para várias finalidades e uma das principais é impedir que o mesmo aplicativo seja executado duas vezes.
| 1 | function CreateMutex(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PChar): THandle; stdcall; |
| 2 | {$EXTERNALSYM CreateMutex} |
O exemplo abaixo impede a execução do mesmo aplicativo por mais de uma vez no mesmo computador:
| 01 | program Project1; |
| 02 | |
| 03 | uses |
| 04 | Forms, |
| 05 | Windows, |
| 06 | Dialogs, |
| 07 | Unit1 in 'Unit1.pas' {Form1}; |
| 08 | |
| 09 | {$R *.res} |
| 10 | |
| 11 | var |
| 12 | hMutex: THandle; |
| 13 | begin |
| 14 | hMutex := CreateMutex(nil, true, PChar('MeuNomeUnico')); |
| 15 | if (hMutex <> 0) and (GetLastError = 0) then |
| 16 | begin |
| 17 | Application.Initialize; |
| 18 | Application.CreateForm(TForm1, Form1); |
| 19 | Application.Run; |
| 20 | end else |
| 21 | ShowMessage('Aplicativo já está rodando.'); |
| 22 | end. |
| 23 | |
Utilizando basicamente, o 3º parametro do CreateMutex é aonde informamos qual o nome único utilizaremos, para que na tentativa de criação da sinalização, a Kernel32 verifique se há alguma sinalização de nome igual ( A verificação é em case-sensitive ).
Já que vimos a utilização básica de uma sinalização a nível de kernel podemos entender como o sistema funciona.
Ao utilizar o CreateMutex, criamos uma sinalização mutex controlada e gerenciada pela Kernel32, ou seja, seu aplicativo em nada muda ao chamar esse API.
Como o controle de todos os processos é feito pela Kernel32, em hipótese de travamento de seu programa não há possibilidade da sinalização Mutex ficar retida, pois ao detectar que o processo foi extinto a Kernel32 retira a sinalização automaticamente.
Após criada uma sinalização Mutex, enquanto ela não for fechado ( Utiliza-se CloseHandle para essa finalidade ), a sinalização ficará de posse da primeira execução do aplicativo. Então quando executado pela segunda vez, ao tentar criar uma sinalização com o mesmo nome, a Kernel32 retorna um erro, aonde se é interpretado que a sinalização já existe e assim indicando que o processo já está executado.
A sinalização mutex ( Mutex Object ) poderá ser utilizada de várias formas, compreende-se em sinalização de controle de acessos à algum ponto ou objeto comum a mais de um processo ( Threads ).
A matéria é muito extensa, engloba Threads, Processos, Sinalização e Semaforização de acessos além da vasta acessibilidade de Eventos Kernel32, área que já implica no entendimento de Tokens Privileges. Ou seja, assunto para mais de um artigo
.
Abraço a todos
articles — 4 comments