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.