Delphi - Excluindo um registro do windows variável

|

Todo mundo já deve conhecer sobre a manipulação de registros do Windows através do Delphi, então o que eu vou mostrar é um exemplo prático do que você pode fazer.

Conteúdo dessa postagem:
- Listar pastas de uma determinada chave de registro.
- Buscar através de uma lista de pastas, uma pasta com um caracter coringa.
- Verificar existência de uma chave de registro.
- Excluir uma chave de registro.

Antes de mais nada, temos que declarar a biblioteca Registry no projeto.
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, StdCtrls, Registry;

Já declarada, você poderá manipular variáveis do tipo TRegistry, vou colocar a procedure inteira mas você pode parametrizar ela conforme a sua necessidade.
A procedure abaixo apaga um determinado registro fixo no programa, mas o problema é que a primeira chave é variável, ou seja, não tem como passar um caminho fixo para excluir o registro.
A solução foi executar um loop, buscando pelo caracter coringa, até encontrar o registro a excluir.

Raiz: HKEY_USERS
Chave: S-1-5-21-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxxx\Software\SimonTatham\putty\SshHostKeys\
onde xxxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxxx é variável de computador para computador.
procedure ApagaRegistrosWindows;
var i : integer;
    RegWin : TRegistry;
    achou, fim : boolean;
    Chaves : TStringList;
begin
   RegWin := TRegistry.Create; // Chama o construtor do objeto
   RegWin.RootKey := HKEY_USERS; // seta raiz do registro

   Chaves := TStringList.Create; // cria uma stringlist para referência
   RegWin.OpenKey('', False); // abre a pasta da raiz caso exista
   RegWin.GetKeyNames(Chaves); // associa as pastas para a stringlist

   // inicializa variáveis
   i := 0;
   achou := false;
   fim := false;

   while ((not achou) and (not fim)) do
   begin
      // busca a chave que contém 'S-1-5-21' e não contenha a palavra 'Classes'
      if ((Pos('S-1-5-21', Chaves.Strings[i]) > 0) and (Pos('Classes', Chaves.Strings[i]) = 0)) then
         achou := true
      else if i = Chaves.Count-1 then // se estiver no último registro, termina
         fim := true
      else Inc(i); // se não encontrar, incrementa o contador
   end;

   if achou = true then
   begin
      // facilitando a vida do programador
      Chaves.Strings[i] := Chaves.Strings[i] + '\Software\SimonTatham\PuTTY\SshHostKeys';

      // verifica se o registro existe
      if RegWin.KeyExists(Chaves.Strings[i]) then
         RegWin.DeleteKey(Chaves.Strings[i]); // apaga o registro se existir
   end;

   RegWin.CloseKey; // Fecha a chave e o objeto
   RegWin.Free; // Libera o registro da memória
   Chaves.Free; // Libera a stringList da memória
end;

SQL Server - Analisando qual campo foi alterado via trigger

|


Muitas vezes precisamos validar se uma "coluna x" foi alterado dentro de uma trigger.
No SQL Server, temos duas maneiras de fazer tal validação.

1) A função Update(nome_coluna) retorna um valor boolean se tal coluna for alterada;
2) E a função Columns_Updated() que retorna um varbinary;

1) Para comparar duas colunas de uma tabela sem se independente das outras, o Update resolve bem o problema.

If (Update(col1) And Update(col2))
   Print 'Coluna 1 e Coluna 2 foram alteradas.'


2) Agora, se você quiser comparar uma coluna que depende de outras, aí você terá que utilizar o Columns_Updated(). Essa função retorna uma variável onde cada byte representa 8 colunas da sua tabela. Começando da esquerda para a direita, o primeiro byte referencia da 1ª a 8ª coluna. O segundo byte referencia da 9ª a 16ª coluna e assim por diante.

Falando em linguagem binária, temos 8 bits em que cada posição desse bit referencia a 8 colunas da sua tabela.
Exemplo 1: 00000000 (Nenhuma alteração nas colunas)
Exemplo 2: 00000100 (A 3ª coluna foi alterada)
Exemplo 3: 10100000 (A 6ª e 8ª colunas foram alteradas)

Em decimal, temos:

Exemplo 1: 0 (Nenhuma alteração nas colunas)
Exemplo 2: 4 (A 3ª coluna foi alterada)
Exemplo 3: 160 (A 6ª e 8ª colunas foram alteradas)

Bom, chega de falar de teoria e vamos ao código que tudo vai ficar mais simples.
-- Exemplo 1:
-- O valor da comparação é feito em decimal e é utilizado uma comparação binária "&" para retonar o valor inteiro da função Columns_Updated()

If (Columns_Updated() & 4) = 4
   Print 'Somente a terceira coluna foi alterada'
   
-- Exemplo 2:

If (Columns_Updated() & 0) = 0
   Print 'Não houve alteração na tabela'
   
-- Exemplo 3:

If (Columns_Updated() & 160) = 160
   Print 'Colunas 6 e 8 foram alteradas'


2a) Mas e se a minha tabela tiver mais de 8 colunas? Bom, aí teremos que ler cada byte separadamente, pois cada byte corresponde somente a 8 colunas como já foi dito anteriormente. Os exemplos abaixo são somente para uma tabela de até 16 colunas
-- Exemplo 1a:
-- O valor da comparação é feito em decimal e é utilizado uma comparação binária "&" para retonar o valor inteiro da função Columns_Updated()
-- O primeiro substring analisa as 8 primeiras colunas (1ª a 8ª) e depois as 8 próximas colunas (9ª a 16ª)

If ((Substring(Columns_Updated(),1,1) & 4) = 4) And 
    (Substring(Columns_Updated(),2,1) & 1) = 1))    
   Print 'Colunas 3 e 9'
   
-- Exemplo 2a:

If ((Substring(Columns_Updated(),1,1) & 160) = 160) And 
    (Substring(Columns_Updated(),2,1) & 21) = 21))      
   Print 'Colunas 6, 8, 9, 11 e 13 foram alteradas'
   
-- Exemplo 3a:
-- ao invés de utilizar um número decimal, é possível fazer o cálculo através da função power(2, pos_coluna-1)

If ((Substring(Columns_Updated(),1,1) & (power(2, 6-1) + power(2, 8-1)) ) = power(2, 6-1) + power(2, 8-1)) And 
    (Substring(Columns_Updated(),2,1) & power(2, 1-1) + power(2, 3-1) + power(2, 5-1) ) = power(2, 1-1) + power(2, 3-1) + power(2, 5-1)))
   Print 'Colunas 6, 8, 9, 11 e 13 foram alteradas'   
   
-- Exemplo 4: OR (para tabelas com até 8 colunas)
-- é possível validar através do "OU" binário "|"
-- valida se somente as colunas 6 ou 8 foram alterados

If (Columns_Updated() | 160) = 160
   Print 'Colunas 6 ou 8 foram alteradas'
   
-- Exemplo 5: XOR (para tabelas com até 8 colunas)
-- é possível validar através do "OU Exclusivo" binário "^"
-- valida se as colunas 6 ou 8 não foram alterados

If (Columns_Updated() ^ 160) = 160
   Print 'Colunas 6 ou 8 não foram alteradas'


Fim, ufa :)

Shell Script - Criação de um script de Backup com o p7zip ou 7za e compactar somente as subpastas de um diretório.

|

Para realizar um script de backup com a utilização do p7zip ou 7zip, é necessário informar o caminho onde fica o bin do 7zip "/usr/local/bin/7za" pois se utilizar somente o comando "7za" no script, não irá funcionar utilizando o cron para iniciar o script. Portanto para utilizar o p7zip no cron do linux é necessário passar todo o caminho do bin (7za).
Para realizar o backup por de um diretório e compactando somente as subpastas, utilizei o script abaixo.

#!/bin/sh
# Para melhor visualização do script irei colocar variáveis no script.
# Para informar que é uma viável é só colocar um $ antes da variável.
# Para exempĺo irei realizar a compactação da pasta /root e irei colocar os arquivos de backup em /BKP.


##### Setando as variáveis
# Arquivos de backup.
BKP_PASTA=/BKP/

# Temporário para ler as pastas do diretório.
TMP=/BKP/txt.tmp

# Setando a variável "x" para 1 (Esse onde ele começa a pegar a linha)
x=1

# Captura o número de pastas. (no caso no /root/) 
N_PASTAS=$(ls -d /root/*/ |wc -l)


### Inicio do Script
cd /root
# Captura as pastas do diretório (no caso o /root)
ls -d * > $TMP

# Utilizo o while para ele percorrer as linhas da variável TMP para realizar o backup das pastas
while [ $x -le $N_PASTAS ];
do

# Neste ponto ele lê a linha onde a variável "x" onde está apontado
L_TMP=$(cat $TMP | head -n $x | tail -n 1);

# Realiza o processo de compactação com o 7za
# Como dito, para a utilização do p7zip ou 7za deve-de fazer da forma abaixo
# Neste ponto ele faz a compactação e joga para o diretório de Backup definido anteriormente e compacta a pasta onde o "x" está apontando.
/usr/local/bin/7za a -sfx -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on tar -jcvf $BKP_PASTA$L_TMP.exe  /root/$L_TMP 

# Incrementa mais 1 no x, fazendo assim pulando para a pŕoxima linha.
x=$((x+1));
}

done; # Sai do While

##### FIM

IBM DB2 - Criando Tabela temporária a partir de um Select

|

Criando Tabela temporária a partir de um Select:

DECLARE GLOBAL TEMPORARY TABLE TAB_TEMP AS (SELECT NOME FROM TABELA) WITH NO DATA

OBS: com esta instrução não é retornado dados do select.

Criando uma tabela temporária a partir de um Select e inserindo os registros do Select:
DECLARE GLOBAL TEMPORARY TABLE TAB_TEMP AS (SELECT * FROM TABELA) DEFINITION ONLY ON COMMIT PRESERVE ROWS;
INSERT INTO SESSION.TAB_TEMP SELECT * FROM TABELA;

IBM DB2 - Criando tabela temporária

|

O comando SQL abaixo demonstra como criar uma tabela temporária no banco de dados IBM DB2:

DECLARE GLOBAL TEMPORARY TABLE TEMP_EMP
   (EMPNO CHAR(6) NOT NULL,
    NOME VARCHAR(12) NOT NULL,
    ATIVO CHAR(1) NOT NULL,
    RAMO VARCHAR(15) NOT NULL,
    DEPTO CHAR(3),
    FONE CHAR(4)
   );

Delphi - Impedir que abra duas instâncias da mesma aplicação

|

O código abaixo demonstra como impedir que seja aberto duas instâncias da aplicação Delphi. Essa consistência deve ser colocada na unit do projeto(.dpr) de sua aplicação.

Var hd : THandle;
Begin
   hd := FindWindow('TApplication', 'NomeDaAplicação'); // Localizando janela de acordo com o nome da aplicação
   If hd = 0 Then // Verificando se a aplicação com o nome passado acima já esta aberto.
   Begin
      Application.Title := 'NomeDaAplicação'; // Definindo um nome para aplicação
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
   End;
End.

C# - Colorir linha do DataGridView

|

O trecho de código abaixo demonstra de forma simples como colorir um linha do DataGridView utilizando o evento RowPrePaint.

private void DataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
   DataGridView dgv = sender as DataGridView;
   /* Pegando valor de uma celula do DataGridView */
   string valor = dgv.Rows[e.RowIndex].Cells[1].Value.ToString();
   if (/*Sua Condição. Ex: valor = 1 */)
   {
      /* Alterando cor do Fundo */
      dgv.CurrentRow.DefaultCellStyle.BackColor = Color.Blue;
      /* Alterando cor da fonte */
      dgv.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red;
   }
}