quarta-feira, 18 de novembro de 2009

Arquivo mapeado e Serviço do Windows

Enfim! Valeu a pena não ter desistido! :)

Vamos lá:

Problema:

Criar um arquivo mapeado entre um Serviço do Windows em uma aplicação GUI. O objetivo é acompanhar em tempo real o tamanho de uma pilha de objetos.

Solução:

Para criar um arquivo mapeado:

procedure TGatewayCTI.CriarArquivoCompartilhado;
var
cErro : Cardinal;
begin
Self.FMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,100,PChar('Session\FILA_GATEWAY'));
if (Self.FMappingFile <> 0) then
begin
cErro := GetLastError;
if (cErro = ERROR_ALREADY_EXISTS) then
begin
CloseHandle(Self.FMappingFile);
Self.FMappingFile := OpenFileMapping(FILE_MAP_ALL_ACCESS,False,PChar('Session\FILA_GATEWAY'));
GerarLogTipoInformation(True,84734903,[' > Sucesso ao abrir arquivo mapeado!'])
end else
begin
GerarLogTipoInformation(True,894733,[' > Sucesso ao criar arquivo mapeado!']);
end;
end else
begin
GerarLogTipoErro(True,49874309,[Format(' > Erro ao criar arquivo mapeado: [%d - %s]',[cErro,SysErrorMessage(cErro)])]);
end;
end;


Para gravar um valor:

procedure TGatewayCTI.AtualizarQuantidade(piIncremento: Integer);
var
Ptr: PChar;
begin
try
if (Self.FMappingFile <> 0) then
begin
Self.FCountQueue := Self.FCountQueue + piIncremento;
if (piIncremento < 0) then
begin
Self.FCountProcessed := Self.FCountProcessed + Abs(piIncremento); 
end;

Ptr := MapViewOfFile(Self.FMappingFile,FILE_MAP_WRITE,0,0,0);
StrPLCopy(Ptr,Format('Na pilha: [%d] - Processadas: [%d]',[Self.FCountQueue,Self.FCountProcessed]),100);
UnmapViewOfFile(Ptr);
end;
except
on E: Exception do
GerarLogTipoException(58679343,E,'Arquivo mapeado');
end;
end;
Para ler o valor:
procedure TfPrincipal.AtualizarValor;
var
Ptr : PChar;
begin
if (Self.FMappingFile <> 0) then
begin
Ptr := MapViewOfFile(Self.FMappingFile,FILE_MAP_READ,0,0,0);
Self.pCount.Caption := Format('%s',[Ptr]);
UnmapViewOfFile(Ptr);
Application.ProcessMessages;
end else
begin
Self.pCount.Caption := 'Arquivo mapeado não disponivel';
end;
end;
Importantíssimo:
Para compartilhar o arquivo entre um serviço e um aplicativo GUI, coloque a palavra 'Session\' antes do nome do arquivo.

Minha lista de blogs