ADSENSE

ADSENSE

terça-feira, 28 de fevereiro de 2012

Listar arquivos de diretórios


Boa Tarde .
Esta dica abaixo serve pra listar os arquivos de um determinado diretório, e seu sub diretórios.
Eu usei um ListBox pra listar os arquivos, mas fica a critério de cada um.

procedure TForm1.ListarArquivos(Diretorio: string; Sub:Boolean);

function TemAtributo(Attr, Val: Integer): Boolean;
begin
   Result := Attr and Val = Val;
end;

var
  F: TSearchRec;
  Ret: Integer;
  TempNome: string;
begin
   Ret := FindFirst(Diretorio+'\*.*', faAnyFile, F);
   try
      while Ret = 0 do begin
         if TemAtributo(F.Attr, faDirectory) then begin
            if (F.Name <> '.') and (F.Name <> '..') then
               if Sub = True then begin
                  TempNome := Diretorio+'\' + F.Name;
                  ListarArquivos(TempNome, True);
               end;
         end else begin
         ListBox1.Items.Add(Diretorio+'\'+F.Name);
      end;
      Ret := FindNext(F);
   end;
   finally
      FindClose(F);
   end;
end;


quinta-feira, 23 de fevereiro de 2012

Atualizações de sistemas


A atualização de aplicativos sempre causa um pouco de dor de cabeça especialmente se você possui um parque grande de clientes instalados.

O quanto mais fácil seria este processo se ao invés de ir máquina a máquina trocando os arquivos você pudesse disponibilizar os arquivos em uma pasta compartilhada e ao abrir sua aplicação ela automaticamente se atualizasse.

Passo 0 – Sempre antes de realizar qualquer alteração em suas aplicações crie uma cópia de backup para sua própria segurança.

Passo 1 – Abra sua aplicação e no menu “Project>>Options” abra as opções do seu projeto. Na aba “Version Info” habilite as opções “include version information in project” e “Auto-increment buid number”.

Ao habilitar estas duas opções sua aplicação passará a ser versionada e número será automaticamente incrementado toda vez que você fizer um novo build no seu projeto. Estas opções serão úteis mais adiante no nosso projeto.

Passo 2 – Vamos incluir duas functions a sua aplicação:

//Retorna o build de um arquivo
function GetBuildInfo(prog: String): String;
var
   VerInfoSize: DWORD;
   VerInfo: Pointer;
   VerValueSize: DWORD;
   VerValue: PVSFixedFileInfo;
   Dummy: DWORD;
   V1, V2, V3, V4: Word;
begin
   VerInfoSize := GetFileVersionInfoSize(PChar(prog),Dummy);
   GetMem(VerInfo,VerInfoSize);
   GetFileVersionInfo(PChar(prog),0,VerInfoSize,VerInfo);
   VerQueryValue(VerInfo,'',Pointer(VerValue),VerValueSize);
   with VerValue^ do begin
      V1 := dwFileVersionMS shr 16;
      V2 := dwFileVersionMS and $FFFF;
      V3 := dwFileVersionLS shr 16;
      V4 := dwFileVersionLS and $FFFF;
   end;
   FreeMem(VerInfo,VerInfoSize);
   result := Copy(IntToStr(100 + v1),3,2) + '.' + Copy(IntToStr(100 + V2),3,2) + '.' + Copy(IntToStr(100 + V3),3,2) + '.' + Copy(IntToStr(100 + V4),3,2);
end;

//Retorna o tamanho de um arquivo em bytes
function DSiFileSize(const fileName: string): int64;
var
   fHandle: DWORD;
begin
   fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   if fHandle = INVALID_HANDLE_VALUE then
      Result := -1
   else try
      Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi);
   finally
      CloseHandle(fHandle);
   end;
end;

Passo 3 – Vamos declarar em uses ShellAPI

Passo 4 – Vamos precisar armazenar o local onde o arquivo atualizado estará disponível. Neste exemplo estaremos salvando a informação em um arquivo de configuração (arquivo ini). Mas você pode salvar esta informação no registro do Windows ou onde achar mais apropriado.

Passo 5 – Agora vamos criar a procedure que vai realmente atualizar a aplicação:

procedure Atualiza_Versao_Aplicacao;
var
   versao_local, versao_servidor : string;
   tamanho_original, tamanho_recebido : integer;
   local_arquivo_servidor : string;
   iArq : Tinifile;
begin
   //Verifico onde esta armazenado o arquivo a ser atualizado
   if FileExists(GetCurrentDir + '\CONFIG.INI') then begin
      try
         iArq := TInifile.Create(GetCurrentDir + '\CONFIG.INI');
         local_arquivo_servidor := iArq.ReadString('UPDATE','LOCAL','\\SERVIDOR\PASTA\ARQUIVO.EXE');
      finally
         iArq.Free;
      end;
   end;
   //Armazeno a versão da aplicação atualmente em uso
   versao_local := GetBuildInfo(GetCurrentDir + '\ARQUIVO.EXE');
   //Armazeno a versão do aplicação que esta disponivel no servidor
   versao_servidor := GetBuildInfo(local_arquivo_servidor);
   //Comparo as versões
   if versao_local <> versao_servidor then begin
      //Guardo na váriavel o tamanho do arquivo que esta no servidor
      tamanho_original := DSiFileSize(local_arquivo_servidor);
      //Copio a versão que esta no servidor para o computador atual
      CopyFile(PChar(local_arquivo_servidor),PChar(GetCurrentDir+'\ARQUIVO.NEW'),False);
      //Guardo na váriavel o tamanho do arquivo copiado
      tamanho_recebido := DSiFileSize(GetCurrentDir+'\ARQUIVO.NEW');
      //Verifico se o arquivo copiado chegou intacto
      if tamanho_original = tamanho_recebido then begin
         //Apago se existir versão antiga
         DeleteFile('ARQUIVO.OLD');
         //Renomeio o arquivo atual
         RenameFile('ARQUIVO.EXE', 'ARQUIVO.OLD');
         //Renomeio o arquivo novo para poder usa-lo
         RenameFile('ARQUIVO.NEW', 'ARQUIVO.EXE');
         //Informo que a aplicação foi atualizado com sucesso
         ShowMessage('Aplicação atualizada com sucesso!');
         //Mando abrir a nova versão do teclado
         ShellExecute(0,Nil,PChar(GetCurrentDir+'\ARQUIVO.EXE'),'', Nil, SW_SHOWNORMAL);
         //Fecho a aberta
         Close;
      end else begin
         //Caso o arquivo copiado não seja copiado com sucesso
         ShowMessage('Copia de arquivo falhou! Tente novamente!');
      end;
   end else begin
      //Se a aplicação já estiver atualizada
      ShowMessage('Aplicativo já possui a ultima atualização disponível!');
   end;
end;

Passo 6 – Você pode chamar a procedure de atualização no onClick de um Botão, criar uma tecla de atalho, adiciona-la no activate do form. Na maneira que lhe for mais conveniente.

Passo 7 – Lembre-se de que o usuário que estiver logado no computador na hora em que for ser atualizada a aplicação deve ter permissões administrativas na pasta onde a aplicação esta instalada e que também ter permissões de acesso a pasta onde a nova versão foi armazenada.

Com esta rotina você pode atualizar não só o executável da sua aplicação, mas todos os arquivos que precisar. Basta usar sua imaginação.

quarta-feira, 22 de fevereiro de 2012

Gerenciador de MySQL

Pra aqueles que utilizam o MySQL com Base de Dados, e tem algumas dificuldades em  achar um front-end pro mesmo ai vai um link pra um gerenciador leve e eficiente.
http://www.heidisql.com/download.php na pagina que se abre clica em Installer(Mirror).
Façam um bom proveito.

Como utilizar const em functions e procedures.


Neste artigo do Vale do Delphi, quero compartilhar com as pessoas que acessam nosso blog este facilitador na hora de passar parâmetros para funções e procedures chamado de const.

Exemplos de funções e parâmetros:

procedure Passa_Parametros(Parm1, Param2, Param3: variant); (tradicional)

Neste exemplo (tradicional) preciso sempre informar os três parâmetros independente de sua necessidade em determinados momentos, utilizando const, você poderá definir os valores padrões dos parâmetros e ocultar sua instrução quando desejar, veja no exemplo abaixo:

procedure Passa_Parametros(const Param1: Integer = 0; const Param2: String = ‘VALE DO DELPHI’; const Param3: Double = 0);

Na hora de chamar a procedure posso chamar assim: Passa_Parametros ou Passa_Parametros (1) ou Passa_Parametros(1, ‘TESTE’) ou Passa_Parametros(1, ‘TESTE’, 2).

Espero que tenham gostado a aprendido com a matéria.

Atenciosamente,
Cléber.

Função pra compactar e descompactar arquivos em delphi

Boa tarde amigos delphianos.
Estou publicando duas procedures que serve pra compactar e descompactar vários arquivos em Delphi usando a lib.  zlib do próprio Delphi.

Só se deve ter o cuidado que o arquivo compactado só se consegue descompactar usando a função de descomprimir que abaixo estou publicando, isso porque a compactação é feita em modo de stream e função própria. Talvez tenha algum programa que consiga descompactar mas não foi testado.
Mas vamos as procedure.

procedure Comprimir(ArquivoCompacto: TFileName; Arquivos: array of TFileName);
var
  FileInName: TFileName;
  FileEntrada, FileSaida: TFileStream;
  Compressor: TCompressionStream;
  NumArq, I, Len, Size: Integer;
  Fim: Byte;
begin
  FileSaida := TFileStream.Create(ArquivoCompacto, fmCreate or fmShareExclusive);
  Compressor := TCompressionStream.Create(clMax, FileSaida);
  NumArq := Length(Arquivos);
  Compressor.Write(NumArq, SizeOf(Integer));
  try
    for I := Low(Arquivos) to High(Arquivos) do begin
      FileEntrada := TFileStream.Create(Arquivos[I], fmOpenRead and fmShareExclusive);
      try
        FileInName := ExtractFileName(Arquivos[I]);
        Len := Length(FileInName);
        Compressor.Write(Len, SizeOf(Integer));
        Compressor.Write(FileInName[1], Len);
        Size := FileEntrada.Size;
        Compressor.Write(Size, SizeOf(Integer));
        Compressor.CopyFrom(FileEntrada, FileEntrada.Size);
        Fim := 0;
        Compressor.Write(Fim, SizeOf(Byte));
      finally
        FileEntrada.Free;
      end;
    end;
  finally
    FreeAndNil(Compressor);
    FreeAndNil(FileSaida);
  end;
end;
procedure Descomprimir(ArquivoZip: TFileName; DiretorioDestino: string);
var
  NomeSaida: string;
  FileEntrada, FileOut: TFileStream;
  Descompressor: TDecompressionStream;
  NumArq, I, Len, Size: Integer;
  Fim: Byte;
begin
  FileEntrada := TFileStream.Create(ArquivoZip, fmOpenRead and fmShareExclusive);
  Descompressor := TDecompressionStream.Create(FileEntrada);
  Descompressor.Read(NumArq, SizeOf(Integer));
  try
    I := 0;
    while I < NumArq do begin
      Descompressor.Read(Len, SizeOf(Integer));
      SetLength(NomeSaida, Len);
      Descompressor.Read(NomeSaida[1], Len);
      Descompressor.Read(Size, SizeOf(Integer));
      FileOut := TFileStream.Create(
        IncludeTrailingBackslash(DiretorioDestino) + NomeSaida, 
        fmCreate or fmShareExclusive);
      try
        FileOut.CopyFrom(Descompressor, Size);
      finally
        FileOut.Free;
      end;
      Descompressor.Read(Fim, SizeOf(Byte));
      Inc(I);
    end;
  finally
    FreeAndNil(Descompressor);
    FreeAndNil(FileEntrada);
  end;
end;

Um exemplo de uso, seria:
var
  //vetor para guardar os nomes dos arquivos a ser compactados
  ListaArquivos: Array of TFileName;
begin
  //define o tamanho do vetor (qtde. de arquivos)
  SetLength(ListaArquivos, 2);
  //preenche a lista com os arquivos
  ListaArquivos[0] := 'C:\Windows\Bruma.bmp';
  ListaArquivos[1] := 'C:\Windows\Cafezinho.bmp';
  //executa a compactação, gerando o arquivo C:\Compactado.xxx
  Comprimir('C:\Compactado.xxx', ListaArquivos);
  //cria um diretório de teste para descompactarmos
  MkDir('C:\Descompactado');
  //executa a descompactação no diretório criado
  Descomprimir('C:\Compactado.xxx', 'C:\Descompactado');
end;