30 de abril de 2009

Criando aplicações HTML

Uma aplicação HTML é, a grosso modo, uma página HTML que é carregada localmente – e não a partir da Web – e que, portanto, não sofre as restrições de segurança aplicadas a páginas vindas da rede. Aplicações HTML podem, portanto, conter e executar as mesmas coisas que páginas HTML comuns : exibir interface gráfica interativa, embutir animações flash, formatar informações com CSS, executar scripts, etc.. Dessa forma, são uma alternativa interessante e rápida para criar automações de tarefas do dia-a-dia, tanto as mais simples (como copiar arquivos) quanto as mais complexas, envolvendo, por exemplo, acesso a banco de dados através de ADO ou outras estruturas através de COM.

Escrevi um post sobre automação envolvendo Scripts, COM e serviços do Windows e vou usar o mesmo exemplo para criar uma aplicação HTML, mostrando o quão flexível e poderosa pode ser essa técnica.

Na prática, há duas coisas que diferenciam um HTML comum de uma aplicação HTML :
1) o nome do arquivo da aplicação possui extensão HTA ao invés de htm ou html;
2) internamente, a presença da tag HTA:APPLICATION, que descreve algumas características da aplicação, como borda da janela, ícone, etc.
Segue o trecho do HTML de exemplo onde ocorre a tag HTA:APPLICATION :
<title>Lista de Serviços do Windows</title>
<HTA:APPLICATION ID="AppServices"
APPLICATIONNAME="serviços"
BORDER="dialog"
ICON=””
SHOWINTASKBAR="yes"
WINDOWSTATE="maximize"
SCROLL="auto"
SYSMENU="yes"
>

Onde
ID é um nome único para permitir acessibilidade à tag via script;
APPLICATIONNAME é o nome dado à aplicação;
BORDER indica o tipo de borda que a janela da aplicação possuirá, isto é, se o usuário verá uma borda e se a janela poderá ser redimensionada;
ICON é o caminho para um arquivo externo contendo o ícone que representará a aplicação; no exemplo, está vazio para evitar ter um arquivo externo;
SHOWINTASKBAR indica se a aplicação deve ou não aparecer na barra de tarefas do Windows;
WINDOWSTATE configura como a janela para a aplicação deve aparecer; no exemplo, ela estará maximizada;
SCROLL configura a exibição de barras de rolangem na página; auto significa que elas aparecerão somente se for necessário;
SYSMENU indica se o menu de sistema é acessível pelo usuário na aplicação.

Há outras propriedades disponíveis que não aparecem no exemplo. A lista completa pode ser consultada aqui.

Na parte HTML propriamente dita, implementei o evento onload da tag body, chamando a rotina em VBScript que lista todos os serviços instalados na máquina, se estão em execução no momento e o método de inicialização deles.
<body onload="ListaServicos ()">

Assim, ao dar um duplo clique no arquivo HTA, ele carregará a aplicação e renderizará automaticamente a lista.

Para entender como funciona a rotina, veja meu outro post sobre automação de serviços através de scripts. Para fazer download do exemplo, clique aqui.
O exemplo não é um primor de interatividade mas ilustra bem o poder dos scripts e como usá-los rapidamente para criar uma aplicação HTML. Como é um arquivo texto simples contendo tags HTML, qualquer editor de texto serve para criá-lo; e também não é preciso compilá-lo.

29 de abril de 2009

Lançamento do Windows 7

Por causa de sua participação no mercado, cada vez que a Microsoft lança uma versão nova do Windows gera bastante ansiedade em quase todo mundo que usa computador. E muitas perguntas : Será que meus programas continuarão funcionando ? A que novas brechas de segurança estarei sujeito ? Quantos problemas de execução ainda serão encontrados até que a versão esteja realmente estável e confiável ?

Essa onda de ansiedade está ocorrendo agora com o Windows 7, prometido pela Microsoft para o início de 2010 mas desejado por Bill Gates que saia em definitivo ainda em 2009. Para minimizar essa ansiedade, a Microsoft tem publicado notas na mídia com prévias de recursos e versões de teste. Ainda esta semana, a partir do dia 30 de abril, estará disponível para download um Release Candidate para desenvolvedores e a partir de 5 de maio para o público em geral - veja aqui nota publicada no IDG Now !.

Por exemplo, tem sido divulgado que o Windows 7 terá um "modo XP". Isto é, programas feitos para Windows XP executarão normalmente no Windows 7, através da tecnologia do Virtual PC. O fato de muitos programas terem tido problemas para executar no Windows Vista é um dos argumentos mais usados pelos usuários para não migrar do XP e o tal "Modo XP" é um recurso claramente talhado para vencer essa resistência. Veja aqui nota sobre o Modo XP na Info Online.

Outra nota publicada para tentar vencer resistências : a famigerada tela User Account Control (UAC) do Windows Vista deverá ser acionada bem menos vezes. Essa é aquela tela para aumentar a segurança da operação no Windows Vista pedindo intervação do usuário para confirmar praticamente tudo que se faz no sistema Operacional. Veja aqui a nota publicada no IDG Now !.

Ainda assim, uma pesquisa conduzida pela Dimensional Research com cerca de 1.100 profissionais de TI revela que nada menos que 84% deles não pretende adotar o Windows 7 no ano que vem e que 72% deles são mais preocupados em ter que migrar para o Windows 7 do que ter que ficar com um Windows XP desatualizado. Um resumo do resultado pode ser encontrado aqui e a versão completa aqui.

28 de abril de 2009

Ligando .NET e C++ Win32 numa mesma solução

Não é tão comum, mas pode acontecer ter que misturar codificação .NET com codificação Win32. No caso da ABC71, onde temos um legado grande de regras de negócio - para quem não conhece, o 71 do nome é o ano de fundação da empresa - mudar de tecnologia não é um processo simples.
No momento, estamos trabalhando nosso ERP para que ele seja acessível via Web de forma nativa, isto é, sem ter que apelar para gambiarras do tipo "distribuir a aplicação Windows dentro de um VNC ou WTS". O desafio foi fazer isso sem perder todo o conjunto de regras de negócio que já temos validadas e funcionando na versão Windows.

A solução foi incluir um Web Service que recebe solicitações de um applet Java e as distribui para nossas bibliotecas de regras de negócio. Mas, por questão de facilidade no desenvolvimento, o Web Service é um código gerenciado .NET enquanto nossas bibliotecas são em C++ Win32 - portanto, não-gerenciadas. Foi preciso, então, criar uma camada capaz de permitir que esses dois tipos de código se comunicassem.

Pesquisando na Internet, encontrei uma ferramenta que atendeu plenamente esse requisito. Ela se chama SWIG ou Simplified Wrapper and Interface Generator. Apesar de ser uma aplicação simples, sem interface gráfica, é bastante poderosa, permitindo encapsular chamadas de rotinas C++ em diversas linguagens (C#, Java) e em scripts (PERL, Python, Ruby).

No caso da ABC71, montamos uma classe C++ que gerencia chamadas às nossas bibliotecas com as regras legadas e encapsulamos essa classe com SWIG para podermos direcionar a ela as chamadas geradas pelo usuário no applet Java.

Na prática, uma declaração simplificada da classe é assim :


class TWTransactionManager : public BTransaction
{
public:
TWTransactionManager (void);
virtual __fastcall ~TWTransactionManager (void);

virtual TMessageContent getReply (void);
virtual TdomDocument *getDomReply (void);

TWSession *getSession (void);
};

É necessário informar ao SWIG um arquivo contendo as regras para o encapsulamento. Esse arquivo se parece com o reproduzido abaixo :


%module trManagerWEB
%{
#include "WTransactionManager.h"
%}

%include "WTransactionManager.h"

Onde trManagerWeb é o nome da DLL em que a classe está incluída e "WTransactionManager.h" é o header onde está a declaração textual da classe.

Após a execução do SWIG, serão gerados dois conjuntos de arquivos :
1) fontes C++ que preparam a nossa classe para ser chamada externamente. No exemplo, eles têm que ser incluídos no projeto da biblioteca trManagerWeb.
2) fontes C# para serem incluídos no projeto do Web Service, permitindo trabalhar no C# com as classes C++ declaradas na DLL.

Colaborou Arnaldo Marinho.

26 de abril de 2009

Controlando Serviços do Windows com Batch Files

Batch Files ? Aqueles Batch Files do MS-DOS ? Confesso que apelei no título ... Nos primórdios da Microsoft e até não muito tempo atrás, automatizar tarefas de forma nativa no Sistema Operacional era algo restrito aos famigerados arquivos de lote - os batches. Restritos quando ao número de comandos disponíveis e pobres na sintaxe, tinham, portanto, campo de ação bastante limitado. Desde o Windows 98, a Microsoft inclui em seus sistemas operacionais um componente chamado Windows Script Host, que permite executar VBScripts e JavaScripts como se fossem nativos. Basta criar um arquivo com extensão VBS ou JS com os comandos desejados e o Windows entende como se fosse um programa qualquer, podendo até mesmo ser incluído como uma tarefa agendada.

Qual é a vantagem disso ? Bom, uma linguagem de script é uma linguagem de programação e, portanto, tem muito mais recursos sintáticos que o batch tradicional : você pode criar variáveis, ter laços de controle, desvios condicionais mais robustos, etc. Mas a grande flexibilidade está nos recursos de COM introduzidos pela Microsoft : é possível automatizar tarefas relacionadas a qualquer software que disponibilize suas funções através de interfaces COM. Isso inclui softwares como Excel, Word, ADO (para acesso a Banco de Dados), etc.. Para fora do mundo Microsoft, também há exemplos de softwares que expõe seus objetos dessa maneira : o SAP Business One, o Acrobat Reader, Quick Time, etc.

Voltando ao assunto do título, o acesso aos Serviços do Windows também é possível através de COM. Como em meu computador na ABC71 há muitos serviços que têm uso em poucos momentos, acabei criando "batches" com scripts para iniciá-los antes de acessar o programa que vai necessitar de tal serviço e, ao fechar o programa, encerrar o serviço que não é mais necessário.

Reproduzo abaixo o exemplo comentado que inicia serviços para o VMWare :


' Nome do computador onde estão os serviços.
' o ponto indica que é o computador local
strComputer = "."

' GetObject obtém instância de um objeto existente. No caso, o nome
' esquisito no parâmetro represen
ta o gerenciamento do Windows
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

' Executa uma query no gerente para saber quais são os serviços
' existentes. Note o WHERE : ele
está filtrando apenas os serviços
'VMWare.
Se desejar ver todos os serviços, remova esse filtro.
Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where DisplayName like 'VMWare%'")

' Põe em execução todos os serviços encontrados
For each objService in colServiceList
Wscript.Echo objService.StartService()
Next

' Cria uma instância do objeto COM WScript.Shell, que representa o
' ambiente Windows - arquivos, pastas
e o registro.
Set WshShell = WScript.CreateObject("WScript.Shell")

' Executa o VMWare, especificando que o script deve aguardar o tér-
'mino da execução antes de prosseguir

WshShell.Run """C:\Program Files\VMware\VMware Server\" &_
"vmware.exe""",
0, true

' Finalmente, interrompe os serviços quando o programa terminar.
For each objService in colServiceList
Wscript.Echo objService.StopService()
Next

Salvei este arquivo como StartVMWare.vbs e criei um atalho para ele : basta um duplo clique nesse atalho para executar a automação.

A propósito, os arquivos BAT ainda existem e continuam podendo ser usados pelos saudosistas ...

24 de abril de 2009

Conferência sobre Engenharia de Software

MDA ? Scrum ? CMMi ? Desenvolvimento de software - como a criação de outro produto qualquer - exige planejamento, técnicas e regras bem estabelecidas para produzí-lo, acompanhamento constante e testes para saber se o que está sendo desenvolvido está em conformidade com os requisitos e para garantir a qualidade do resultado final.
Mas há uma infinidade de técnicas para optar em cada fase ... Como escolher a melhor forma de planejar, a melhor forma de gerenciar e testar o projeto, garantindo a qualidade ? Ou é melhor fazer um apanhado de tudo e adaptar as partes que melhor se encaixam na cultura da sua empresa, criando ao final uma metodologia própria ?
A DevMedia, que edita revistas como Clube Delphi, Java Magazine e SQL Magazine, vai realizar em São Paulo nos dias 22 e 23 de maio de 2009 uma conferência abordando todos os aspectos envolvidos no desenvolvimento de Software, oportunidade para conhecer técnicas e pessoas.

Reproduzo abaixo a divulgação do evento :
"
Engenharia de Software Conference - 22 e 23 de Maio, Lapa, São Paulo

Raras são as oportunidades de ter acesso a informações que realmente possam transformar a carreira dos profissionais de TI no Brasil. Esta é uma delas!

Nos dias 22 e 23 de maio, a DevMedia realiza, em São Paulo, a Engenharia de Software Conference. Serão três tracks simultâneos, onde os mais graduados especialistas do ramo discutirão os principais temas da Engenharia de Software atual, entre eles o MPS.Br. Uma metodologia de gerenciamento desenvolvida especialmente para as empresas brasileras.

As explanações vão desde o projeto até os últimos testes de um software, passando pelos diversos conceitos de gerenciamento. Serão 40 horas de conteúdo, distribuídas em 30 palestras. O evento conta com a presença de palestrantes renomados, como Ana Regina Rocha, que será a keynote da conferência. Ela foi uma das idealizadoras do Modelo Mps.Br (Melhoria de Processos do Software Brasileiro), além de ser implementadora e avaliadora credenciada pela SOFTEX e membro do grupo de pesquisa em Engenharia de Software da Universidade Federal do Rio de Janeiro.

Com caráter independente e inovador, a Engenharia de Software Conference não tem o patrocínio de nenhuma das empresas fabricantes, o que garantirá a imparcialidade total, apresentando análise comparatória dos mais variados softwares do mercado. O evento pretende garantir aos profissionais da àrea excelentes oportunidades de aprendizado e network.

Engenharia de Software Conference
Data: 22 e 23 de Maio, das 8:30 às 19h.
Local do Evento: E-Business Park, Espaço do Bosque - Rua Werner Siemens, 111 - Lapa, São Paulo - SP.
"


Como parte da divulgação, a DevMedia distribuirá aos leitores do Balaio Tecnológico 10 assinaturas digitais da revista Engenharia de Software. Então, os 10 primeiros que postarem um comentário nesse post ganharão a assinatura. Se até 30 de abril não houver os 10 comentários, sortearei as assinaturas dentre os seguidores do blog. IMPORTANTE: não esqueçam de colocarem no comentário um email e um nome para podermos entrar em contato.

=> Mais Informações
Portal da DevMedia, Engenharia de Software Conference, Programação das Palestras.

E-mail: evento@devmedia.com.br, Tel.: (21) 3382-5025

23 de abril de 2009

Trabalhando com o Certificate Store em Win32

Há alguns dias, postei um texto mostrando como acessar o Certificate Store do Windows através framework .NET e C#. Como nem todo mundo trabalha com .NET - a ABC71 mesmo usa o C++ Builder, que é Win32 - me perguntaram se é possível trabalhar no Win32 com aquelas classes do exemplo. A reposta curta é sim !
A resposta mais comprida é que isso envolve o uso de um ActiveX distribuído pela Microsoft chamado CAPICOM - Cryptographic Application Programming Interface através de COM.

Portanto, é necessário primeiro importar esse ActiveX, isto é, fazer com que o Delphi ou o C++ Builder gerem um arquivo fonte que nos permita utilizar as classes do CAPICOM. No passo a passo :
  1. Faça o download do CAPICOM e instale-o, caso ainda não o tenha feito.
  2. Localize a biblioteca capicom.dll e execute na linha de comando a seguinte instrução :

    regsvr32 capicom.dll

    Isto registra no Windows a Type Library associada a esse ActiveX.
  3. No Delphi : acesse, dentro do menu Component, a opção Import Component. Obs: Tenho a versão 2007 do Delphi mas não deve ser muito diferente nas outras. No C++ Builder 5, a opção de menu é Import Type Library, dentro do menu Project.
  4. Na janela que aparece, selecione Import a Type Library e pressione Next.
  5. Encontre o CAPICOM Type Libray na lista exibida e pressione Next.
  6. Nessa última tela, apenas marque a opção Generate Component Wrappers pois ele gera um código mais fácil de ser usado no C++ Builder.
  7. Pressione Finish e você tem um fonte com o mapeamento das classes do CAPICOM - inclusive aquelas que mostrei usando C#. Adicione esse fonte aos seus projetos que farão uso do CAPICOM.
Essas classes podem então ser usadas para acessar o Certificate Store e também para assinar documentos, criptografar e descriptografar informações, etc.

A Microsoft, no entanto, considera esse ActiveX obsoleto e recomenda que se use as classes conforme publicado no framework .NET. Além disso, a biblioteca ActiveX tem que ser distribuída e instalada junto com sua aplicação pois pode não estar presente em algumas máquinas.
Em todo caso, inclui alguns posts mostrando como usar as classes do CAPICOM no Delphi.


22 de abril de 2009

Limpeza do Registro do Windows

Instalar novos softwares, atualizar softwares existentes com um nova versão, aplicar patches de atualização do Windows, aplicar security updates de uma série de softwares, etc. É grande a lista das coisas que você faz num computador com Windows que deixa o registry com inconsistências e uma montanha de lixo que só serve para ocupar espaço e deixar mais lenta a máquina.

Estive procurando por um bom programa que ajudasse a manter o registry limpo e há algum tempo venho usando um freeware chamado CCleaner. Ele é capaz de remover as entradas do registry que estão obsoletas, incluindo extensões não usadas de arquivos, controles ActiveX inexistentes, ClassIDs e ProgIDs inválidos, desinstaladores que não existem mais, bibliotecas DLL compatilhadas que não são mais usadas, fontes, arquivos de ajuda, caminhos apontando aplicações que não existem, ícones inválidos de aplicações, atalhos inválidos, etc. É possível selecionar quais dessas buscas serão realizadas e, antes do programa efetivamente remover as entradas, você pode marcar as que quer remover e as que quer manter. Também é dada a oportunidade de se fazer backup - a ser restaurado caso a remoção das entradas cause algum problema.

Na verdade, a função principal do CCleaner é auxiliar na limpeza de disco, removendo caches de softwares (navegadores, java, flash), cookies dos navegadores (há como informar uma lista daqueles que se deseja preservar), arquivos temporários de uma porção de aplicações (incluindo as atualizações do Windows), listas de arquivos abertos recentemente, etc. Há ainda funções avançadas para monitorar e editar a lista de programas que são iniciados junto com o Windows e para incluir pastas de usuário no algorítmo de limpeza – você informa o caminho e quais extensões de arquivo devem ser removidos.

Para quem quer radicalizar, a versão mais recente inclui uma opção que permite apagar também os espaços vazios, isto é, ele não remove só a entrada do aquivo na lista de arquivos do computador mas também os bytes que o compunham, impedindo que se veja rastro dos arquivos.

Mais Informações
Ferramenta CCleaner, registry (registro) do Windows, ambos em inglês.

20 de abril de 2009

Trabalhando com o Certificate Store do Windows

Vem se tornando popular ultimamente o uso de Certificados Digitais para autenticar documentos eletronicamente; a introdução da Nota Fiscal Eletrônica e da Escrituração Digital devem dar um impulso definitivo, já que praticamente todas as empresas terão que adotá-lo para poder assinar as informações enviadas para a Receita Federal.

Mas, o que é na prática um Certificado Digital ? Como é que o Windows trabalha com isso ? O Certificado em si, a grosso modo, é apenas um arquivo onde são armazenadas informações sobre quem outorgou o certificado (uma CA, ou Certificate Authority) e a quem é que foi outorgado o certificado (uma pessoa física ou jurídica ou ainda um computador) bem como um código público (a chave). O Certificado, portanto, associa uma chave pública a uma entidade (empresa, pessoa ou computador). Há um artigo no Wikipedia mais detalhado sobre esse assunto.

Se você (ou sua empresa ou seu computador) é quem recebeu o certificado, você também possui a chave privada, isto é, o código que só você conhece e que será usado para assinar um documento digital, garantindo-lhe a integridade, a autenticidade e conferindo validade jurídica ao documento.

No Windows, o acesso aos Certificados disponíveis se dá de forma centralizada, através do Armazém de Certificados Digitais (ou Certificate Store) . Isto é, uma vez que o certificado foi registrado no computador, não importa onde ele está armazenado : o acesso deve ser feito a partir do store. Para acessá-lo a partir do Windows, vá em Iniciar -> Executar e digite
mmc \windows\system32\certmgr.msc


Esse programa mostra de forma estruturada quais são os certificados presentes em seu computador: aqueles de uso exclusivo de seu usuário (Personal), as Autoridadades Certificadoras (tanto as de nível mais alto na hierarquia certificadora - as root ou raíz - quanto as intermediárias, que dependem da root), etc.

Via programação, o framework do .NET também fornece uma forma estruturada de acessar o Store, através do namespace System.Security.Cryptography.X509Certificates. São basicamente 3 classes para acessar os certificados :
  • X509Store : Representa o acesso ao Store. O construtor dela exige que se estipule qual parte da estrutura deve ser acessada. Use as definições na classe StoreName para identificar, por exemplo, os certificados particulares ("My") ou as Autoridades Certificadoras ("CA"). Pode optar também por informar apenas a localização, através da classe StoreLocation (somente os meus certicados ou todos os certificados presentes no computador).
  • X509Certificate2Collection : Uma lista dos certificados armazenados no Store aberto com a classe anterior.
  • X509Certificate2: Representa um certificado na coleção.
O exemplo abaixo em C# percorre a lista de certificados na Store "My", procurando os válidos e que possuam chave privada.

X509Certificate2Collection lcerts;
X509Store lStore = new X509Store (StoreName.My, StoreLocation.CurrentUser);

// Abre o Store
lStore.Open(OpenFlags.ReadOnly);

// Lista os certificados
lcerts = lStore.Certificates;

foreach (X509Certificate2 cert in lcerts)
{
if (cert.HasPrivateKey && cert.NotAfter > DateTime.Now && cert.NotBefore < DateTime.Now)
{
// Faz o uso do certificado....
// Por exemplo, assinar um docto.
}
}
lStore.Close();

17 de abril de 2009

Aplicações Delphi e C++ Builder 64 bits

A esmagadora maioria do código que compõe o ERP da ABC71 é hoje desenvolvido com o C++ Builder - que era da Borland/Codegear mas hoje é parte da solução para desenvolvimento da Embarcadero. Com o lançamento de versões 64 bits do Windows (principalmente o Vista), tornou-se mais comum procurar software desenvolvido especificamente para essa plataforma.

Software desenvolvido para Win32 não funciona no Win64 ? Funciona ... É um ambiente emulado, isto é, não é nativo, mas funciona. Não usa todo o poder da máquina 64bits, mas funciona. Entretanto, o Cliente comprou um hardware 64bits e fica um pouco frustrado se o software não faz uso pleno desse hardware...

Por essa razão, venho acompanhando há algum tempo os "roadmaps" para Delphi/C++Builder para ver quando é que será liberada uma versão para desenvolvimento de aplicações 64bits. Eles tinham prometido para 2007 ou 2008 mas parece que houve uma reviravolta nos planos e eles decidiram mexer mais embaixo para tornar comum a geração de código de máquina do Delphi e do C++.

Nas palavras de Nick Hodges, da Embarcadero :
" O jeito certo de fazer isso [o back end do compilador gerar código 64 bits] seria reescrever o back end. E, se você vai escrever um novo back end, o jeito certo seria escrever um único back end para ser usado tanto pelo Delphi quanto pelo C++Builder. E, se você vai manter um único back end, você irá querer um back end projetado de tal maneira que seja mais flexível quanto a arquitetura a qual ele se destina."

Com isso, o trabalho acabou ficando muito maior do que aquele planejado inicialmente. Eles estão trabalhando agora com o prazo de meados de 2010 para ter uma versão completa do compilador integrado ao ambiente de desenvolvimento.

O artigo de Nick Hodges fala sobre o futuro do compilador Delphi e é bastante interessante. A versão completa (em inglês) pode ser encontrada aqui.

16 de abril de 2009

Nova versão do HTML

Uma notícia divulgada ontem me chamou a atenção : o consórcio W3c, que gerencia os padrões tecnológicos para a internet, está finalizando o documento relativo à nova versão para a linguagem HTML, a de número 5. A última atualização do HTML está completando 10 anos em 2009 !

Foi publicado um novo rascunho para a versão 5 do HTML e em 2010 eles esperam torná-lo definitivamente o novo padrão. As principais mudanças vêm para simplificar a forma de renderizar as páginas e ainda assim torná-las mais leves e poderosas.

Há incorporação de novas tags para tratar de forma nativa alguns recursos que hoje só são possíveis através da inclusão de bibliotecas externas de scripts implementando Ajax - por exemplo, o efeito de drag-and-drop.

Haverão também tags específicas para tratar conteúdo multimídia nativamente, isto é, sem ter que apelar para as gambiarras da tag OBJECT, por exemplo. E, no sentido de facilitar a criação da renderização das páginas, estão sendo introduzidas tags para criação de seções, como área para cabeçalho e rodapé da página e até para criação e tratamento de imagens em tempo de execução (um canvas !).

Mesmo ainda não tendo a versão definitiva do novo padrão, os fabricantes de software de navegação já estão implementando algumas das novas funcionalidades. Há no Wikipedia uma comparação dos diferentes engines e que características da versão 5 eles já tem implementado e em que estágio dessa implementação elas estão. A comparação pode ser encontrada aqui.

Resta-nos agora torcer para que a efetivação do novo padrão não invalide as páginas que já estão criadas e, bem ou mal, estão funcionando.

Obs: A notícia saiu no Info Online e pode ser acessada na integra aqui.

14 de abril de 2009

Validando um XML contra seu esquema XSD

No dia a dia do profissional de TI, cada vez mais precisamos trabalhar com dados no formato XML. Vira e mexe, é preciso ainda saber se um XML está bem formado, isto é, se ele atende os requisitos dispostos num arquivo de esquema XSD. Um exemplo bem recente disso são os XMLs para envio à Receita Federal no âmbito da Escrituração Digital (SPED) e da Nota Fiscal Eletrônica, onde cada XML tem que seguir regras de formação bem definidas pela Receita, através de arquivos XSD. Os esquemas para NFe podem ser encontrados aqui.

Pesquisando no Google, encontrei uma porção de sites capazes de fazer a validação on-line e também ferramentas - algumas gratuitas, outras pagas. No caso da NFe, a própria Receita Federal faz essa validação mas é preciso submeter ao Web Service deles e aguardar a resposta assíncrona.

Como não encontrei nada que eu achasse prático, resolvi montar um validador por minha conta, para ter à mão sempre que necessário. Pra minha surpresa, descobri que o framework .Net já possui classes para validar um XML e que o uso delas é bastante simples.

Mãos à obra ! Montei uma aplicação simples em C# no Visual Studio 2008 : tem 3 caixas de edição e um botão, como mostra o print screen abaixo:

Ao clicar o botão, o arquivo indicado na caixa Caminho do XML é carregado através de um Reader previamente configurado para realizar a validação enquanto faz a carga. Abaixo, o código comentado do evento de clique no botão :
/* XmlReaderSettings é a configuração de como o XML deve ser lido */
XmlReaderSettings settings = new XmlReaderSettings();
FileStream fs = null;

/* Informa qual é o namespace (se houver) e o caminho do esquema XSD que será usado p/ validar o XML durante a leitura */
settings.Schemas.Add (edNamespace.Text, edXSD.Text);

/* Se dentro do XSD houver referência a outros XSDs externos, pode ser necessário ter certas permissões para localizá-lo. Usa um "Resolver" com as credencias-padrão para obter esse recurso externo. */
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

/* Informa à configuração de leitura do XML que deve usar o "Resolver" criado acima e que a validação deve respeitar o esquema informado no início. */
settings.XmlResolver = resolver;
settings.ValidationType = ValidationType.Schema;

try {
/* Abre o arquivo XML usando o caminho que foi informado na tela. */
fs = new FileStream(edXML.Text, FileMode.Open,
FileAccess.Read);

/* Constrói o leitor de XML, passando o arquivo XML que foi aberto e as configurações que sinalizam como o leitor deve trabalhar. */
XmlReader reader = XmlReader.Create (fs, settings);

/* Constrói um documento XML vazio */
XmlDocument xmlDoc = new XmlDocument();

/* Manda carregar as informações nesse XML através do leitor montado acima. */
xmlDoc.Load(reader);

/* Só chega aqui se carregou tudo OK. */
MessageBox.Show(this, "Validação concluída com sucesso.",
"Aviso", MessageBoxButtons.OK,
MessageBoxIcon.Information);

} catch (Exception exc)
{
/* Se houver erro na validação do XML, uma exceção é levantada e o fluxo vem para esse ponto, exibindo a mensagem de erro.*/
MessageBox.Show(this, exc.Message, "Erro",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}

/* Fecha o stream para liberar o arquivo. */
if (fs != null)
{
fs.Close();
fs.Dispose();
}
Ao final, se foi tudo OK com a carga, tem-se na instância xmlDoc a árvore do XML montada, validada e pronta para ser usada pelo programa.

Obs: No lugar de ler o XML de um arquivo, pode-se usar qualquer tipo de Stream - até mesmo lido da memória (MemoryStream).

Clique aqui para fazer o download do programa. Inclui aqui no blog também alguns posts sobre a construção de arquivos XSD para facilitar o entendimento de como isso funciona.

13 de abril de 2009

Comando INSERT do SQL em tabela com BLOB

Tem algum maluco aí que já tentou incluir via comando SQL um registro numa tabela que tenha um campo BLOB ? Pois é, eu já… Mas tenho um bom argumento em minha defesa : desenvolvi uma ferramenta para ABC71 que permite manipular e transformar dados, isto é, copiar dados de uma tabela num banco de dados, realizar cálculos e outras transformações nesses dados e lançá-los numa outra tabela, num outro banco de dados. Como isso é feito através de um VBScript, foi necessário passar o comando SQL apropriado, incluindo o dado BLOB. O quê ? Já viu isso em algum lugar ? Está certo ... Foi inspirado no DTS da Microsoft.

Voltando ao assunto, em SQL Server, a sintaxe é como no exemplo abaixo :

insert into lare (emp_fil, chave_1, descricao, objetos)
values (10001, 'CONFIG', 'Configuração de Usuário', 0x71720002090000434F445F4E554D00494420437573)

onde o campo “objetos“ é do tipo IMAGE, isto é, é um blob.

O texto 0x (zero xis) no início do valor do BLOB é fixo e indica que se trata de um valor hexadecimal. Os demais valores são a representação hexadecimal de cada um dos bytes que compõem a informação que se deseja gravar. Exemplos : um byte com valor 00000000 é representado como 00, o byte 00000001 vai como 01, o byte 11111111 vai como FF, etc.

Como a limitação de tamanho desse campo é ditada pelo espaço em disco e os valores são bytes, pode-se armazenar qualquer informação com esse método : um texto XML, uma estrutura proprietária de sua aplicação, uma imagem, etc..

Essa sintaxe funciona ligeiramente diferente para Oracle e Postgre. Em Oracle, basta remover o 0x do início e colocar os dados entre apóstrofes :

insert into lare (emp_fil, chave_1, descricao, objetos)
values (10001, 'CONFIG', 'Configuração de Usuário', '71720002090000434F445F4E554D00494420437573')

Em Postgre, é preciso decodificar a informação, chamando a função DECODE. O segundo parâmetro indica que a informação no primeiro parâmetro é um valor hexadecimal :

insert into lare (emp_fil, chave_1, descricao, objetos)
values (10001, 'CONFIG', 'Configuração de Usuário',
DECODE ('71720002090000434F445F4E554D00494420437573',
'hex') )

A função em VBScript listada abaixo aceita como parâmetro um dado binário e produz como resultado a representação hexadecimal desse dado. Esse resultado pode ser usada no INSERT mas é preciso ainda considerar as diferenças de sintaxe citadas antes :
Function BinaryToHex(Binary)
Dim c1, Out, OneByte
For c1 = 1 To LenB(Binary)
OneByte = Hex(AscB(MidB(Binary, c1, 1)))
If Len(OneByte) = 1 Then
OneByte = "0" & OneByte
End If
Out = Out & OneByte
Next
BinaryToHex = Out
End Function

Até a próxima ...

9 de abril de 2009

Criando um applet para o Painel de Controle do Windows

Há certas ocasiões, quando construímos uma aplicação em qualquer linguagem, em que é interessante disponibilizarmos uma forma do usuário configurar tal aplicação através do método padrão do Windows : acessando um ícone no Painel de Controle.

Um exemplo é quando temos um Serviço no Windows. Como serviços não têm interface com o usuário, a melhor solução é permitir a configuração através do Painel de Controle.

Recentemente, tive que montar um Serviço usando Visual Studio e C#. Serviços no VS2008 são fáceis de montar : há um template. Mas não encontrei nenhum modelo de como montar um applet para o Painel de Controle nessa ferramenta. No C++ Builder da Borland, é criado um projeto de DLL cuja função de entrada (Entry Point) tem a seguinte assinatura :

__stdcall int CPlApplet(unsigned hwndCPl, unsigned uMsg, int lParam1, int lParam2);

E toda a tralha associada ao funcionamento do applet vai ai dentro.

Pesquisando no site da Microsoft sobre como criar isso no Visual Studio, me deparei com uma solução que me pareceu bem mais simples e completa. Mais simples porque envolve criar um executável normal, combinado com a criação de entradas no registry para configurar como o applet deve funcionar. E mais completa porque permite criar configurações mais apropriadas para o Painel de Controle no Windows Vista.

Mãos à obra com um exemplo básico :
1) Crie um executável qualquer com interface gráfica, usando a ferramenta de desenvolvimento que você preferir. No meu exemplo, criei como C++ Builder uma aplicação com o nome CONFIG.EXE

2) Crie um GUID para identificar de forma única a sua aplicação. A Microsoft distribui junto com o Visual Studio uma ferramenta para isso : GUIDGen.exe. Para meu exemplo, usei o seguinte GUID : {5E86074E-1E92-4915-B7F8-4531F8DEAD94}

3) Usando o Regedit :
3.1) Localize a chave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace e crie embaixo dela uma nova chave com o seu GUID. Coloque como valor padrão o nome de sua aplicação. Pode ser um nome qualquer, como por exemplo: Config.

3.2) Localize a chave HKEY_CLASSES_ROOT\CLSID e crie embaixo dela uma nova chave com o seu GUID. Nessa chave, edite o valor padrão (default) e informe aí o texto que deve aparecer no Painel de Controle. Pode ser o próprio nome da sua aplicação ou algo mais elaborado, se desejar.

3.3) Para fazer as outras configurações do seu applet, crie os seguintes valores embaixo do valor default do passo anterior :

Nome do valor Tipo do Valor
System.ApplicationName String
Um nome para a sua aplicação. A Microsoft chama isso de nome canônico e permite acessar seu applet a partir da linha de comando. Por exemplo, para um nome ABC71.Config, executar na linha de comando :

control.exe /name ABC71.Config

InfoTip Expandable String
Uma descrição para sua aplicação. Ela aparecerá na forma de um "tooltip" quando você estaciona o mouse sobre o ícone de sua aplicação.
System.ControlPanel.Category String
A lista de categorias do Painel de Controle onde sua aplicação deve aparecer. Se seu applet deve aparecer em mais de uma categoria, separe os números com uma vírgula. Alguns exemplos : 1 (aparência e temas), 5 (performance e manutenção), etc. A lista completa pode ser encontrada aqui.


Mais informações sobre esses valores podem ser encontrado aqui.

3.4) Para associar um ícone, certifique-se que sua aplicação possua um ícone embutido nela. Então, crie uma nova chave embaixo do seu GUID em HKEY_CLASSES_ROOT\CLSID com o nome de DefaultIcon. No valor default dessa chave, inclua o caminho completo para a aplicação que contem o ícone que você deseja e, separado por uma vírgula, o índice de um ícone dessa aplicação. Por exemplo, o valor :
c:\appps\config.exe,0
indica que deve ser usada a aplicação config.exe como fonte e que deve ser exibido o primeiro ícone incluido como recurso no executável (como fazer isso pode valer outro post).
3.5) Por fim, devemos informar qual é a aplicação que dever executada quando o usuário der um clique duplo sobre nosso ícone no painel de controle. Para isso, crie uma nova chave, no mesmo nível do DefaultIcon com o nome de Shell. Embaixo dessa chave, crie uma nova chave, Open. E, para encerrar, nova chave de nome Command e com valor default apontando o camimnho completo da aplicação. Exemplo : c:\appps\config.exe.

Pareceu complicado ? Na verdade é mais trabalhoso do que complicado. Uma vez compreendido o processo, fica fácil de automatizar essa criação na instalação da Solução completa ou através de um arquivo de configuração do registro (extensão .Reg).

Até a próxima !

Alô, mundo !

Pois é ! Essa frase do título traduz exatamente o espírito que me levou a começar um blog.

Quem algum dia já fez um programa na vida sabe que praticamente qualquer aventura com uma nova tecnologia, uma nova linguagem de programação, começa com um protótipo ridículo que simplesmente diz "Alô, mundo !". Invariavelmente, quando esse protótipo ridículo funciona é uma grande alegria : significa que uma etapa fundamental no processo de aprendizado da nova tecnologia foi superado e que estamos prontos para os voos mais altos.

Em qualquer das etapas do aprendizado, no entanto, há muito que bater cabeça pra conseguirmos algo profissional, utilizável, replicável. Pequenos avanços, grandes retrocessos e vice-versa fazem parte desse universo e hoje, como Analista de Pesquisa & Desenvolvimento da ABC71, sou obrigado a conviver diariamente com esses avanços e enroscos e é minha função desenroscar !

É principalmente os resultados dos meus avanços ao estudar novas tecnologias pra ABC71 que pretendo postar nesse blog. Serão dicas em programação e ferramentas, notícias interessantes relacionadas aos assuntos tecnológicos do momento, como evitei certas armadilhas, como resolvi certos problemas, novidades tecnológicas que eu estiver pesquisando, etc.
Coisas com as quais trabalho hoje e que deverão em maior ou menor grau aparecer nesse blog : C++, delphi, .Net, Visual Studio, Notas Fiscais Eletrônicas, XML, MS SQL server, Oracle, SAP Business One, COM, ActiveX, Windows, Report Builder, IntraWeb, Web Services, etc. (o balaio é grande !).

Obviamente, também aceitarei sugestões de assuntos a tratar pois trabalhar num problema sempre amplia nossa bagagem e nunca se sabe quando poderá ser útil.

Por enquanto é isso .... Prometo começar de fato logo com os posts ! Até mais !