Truque 1: Windows Registry e você

O Windows nos deu uma grande provisão para armazenar “delicadezas” e outros materiais… O registro. Porque não o utilizar, em vez de utilizar arquivos de configuração personalizados?

Abaixo estão as funções para criação de uma chave de registro, e para configurar e obter um valor string. Podemos estender os pares get/set para long values e assim por diante. Notar, por favor, com finalidade de programação defensiva, estamos colocando o valor padrão fornecido, caso um valor de registro estiver faltando. Preferimos esta abordagem, a depois chorar com uma exceção. Se pensar diferente, sinta-se, por favor, livre fazer do seu jeito.

Notar também que atualmente, muitos preferem armazenar as informações de configuração em arquivos XML fàcilmente modificáveis e automanuteníveis. Veja qual a sua preferência e dos seus clientes e escolha a melhor opção.

using Microsoft.Win32;
using System.IO;
using System.Security;
///
/// Tenta ler a chave do registro, caso nao exista,
/// serah criada automaticamente
///
public void CheckRegistryKey(string sKeyname)
{
  RegistryKey oRegistryKey =
    Registry.LocalMachine.OpenSubKey("SOFTWARE\\" + sKeyname, true);
  if(oRegistryKey==null)
  {
    oRegistryKey =
      Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE", true);
    oRegistryKey.CreateSubKey(sKeyname);
  }
}
///
/// Verifica a existencide um valor string no caminho fornecido,
/// Caso nao achado, adiciono valor padrao provido
///
public string GetStringValue(string sKeyname,
  string sValueName, string sDefaultValue)
{
  RegistryKey oRegistryKey =
    Registry.LocalMachine.OpenSubKey("SOFTWARE\\" + sKeyname, true);
  if(oRegistryKey==null)
  {
    oRegistryKey =
      Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE", true);
    oRegistryKey.CreateSubKey(sKeyname);
  }
 
  if(oRegistryKey.GetValue(sValueName)==null)
  {
    oRegistryKey.SetValue(sValueName, sDefaultValue);
    return sDefaultValue;
  }
  else
    return (string)oRegistryKey.GetValue(sValueName);
}
///
/// Configura um valor string para a chave dada
///
public void SetStringValue(string sKeyname, string sValueName,
  string sValue)
{
  RegistryKey oRegistryKey =
    Registry.LocalMachine.OpenSubKey("SOFTWARE\\" + sKeyname, true);
  if(oRegistryKey==null)
  {
    oRegistryKey =
      Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE", true);
    oRegistryKey.CreateSubKey(sKeyname);
  }
 
  oRegistryKey.SetValue(sValueName, sValue);
}

Truque 2: Fique consciente do ambiente

Se ainda não for consciente do ambiente, está na hora de sê-lo. Antes de tudo, graças a Deus! Isto é algo para o que sempre devemos estar conscientes. Agora com o .NET, temos classes que nos permitem acessar toda esta riqueza da informação. O que estamos procurando? A versão do OS, a versão do CLR, o nome do usuário, os valores das variáveis do sistema, tais como a pasta temp, a memória física mapeada para a aplicação?

Toda esta valiosa informação pode ser extraída com a classe Environment, como ilustrado abaixo:

using System;
public static void GetEnvironmentInfo()
{
    // Fully qualified path of the current directory
    Console.WriteLine("CurrentDirectory: {0}", Environment.CurrentDirectory);
    // Gets the NetBIOS name of this local computer
    Console.WriteLine("MachineName: {0}", Environment.MachineName);
    // Version number of the OS
    Console.WriteLine("OSVersion: {0}", Environment.OSVersion.ToString());
    // Fully qualified path of the system directory
    Console.WriteLine("SystemDirectory: {0}", Environment.SystemDirectory);
    // Network domain name associated with the current user
    Console.WriteLine("UserDomainName: {0}", Environment.UserDomainName);
    // Whether the current process is running in user interactive mode
    Console.WriteLine("UserInteractive: {0}", Environment.UserInteractive);
    // User name of the person who started the current thread
    Console.WriteLine("UserName: {0}", Environment.UserName);
    // Major, minor, build, and revision numbers of the CLR
    Console.WriteLine("CLRVersion: {0}", Environment.Version.ToString());
    // Amount of physical memory mapped to the process context
    Console.WriteLine("WorkingSet: {0}", Environment.WorkingSet);
    // Returns values of Environment variables enclosed in %%
    Console.WriteLine("ExpandEnvironmentVariables: {0}",
        Environment.ExpandEnvironmentVariables("System drive: " +
        "%SystemDrive% System root: %SystemRoot%"));
    // Array of string containing the names of the logical drives
    Console.WriteLine("GetLogicalDrives: {0}", String.Join(", ",
                      Environment.GetLogicalDrives()));
}

A função funcionará somente com aplicações de console (pois tem Console.Writelines). Para o seu próprio uso, modificá-la como for necessário.

Truque 3: Configurar uma câmera oculta para monitorar uma pasta

Monitorar as atividades do usuário em uma pasta é frequentemente uma tarefa para servidores de aplicação. Por exemplo, tenho um servidor que precisa esperar até o usuário carregar um arquivo XML em uma pasta especial. Uma vez que o usuário colocou o arquivo lá, o servidor faz algum processamento de acordo com o conteúdo do arquivo.

Uma vez sabendo como fazer isto, estou certo que encontrará milhares de aplicações para utilizar este truque. E não está limitado apenas aos eventos de criação do arquivo, podemos monitorar virtualmente todas as atividades que os usuários podem fazer lá..

using System.IO;
// Monitora a pasta C:\Temp e notifica a criatcao de novos arquivos texto
public static void WatchTempFolder()
{
    // Criar o object FileSystemoFileSystemWatcher e configurar suas propriedades
    FileSystemWatcher oFileSystemWatcher = new FileSystemWatcher();
    oFileSystemWatcher.Path = "C:\\Temp";
    oFileSystemWatcher.NotifyFilter = NotifyFilters.LastAccess
          | NotifyFilters.LastWrite | NotifyFilters.FileName |
            NotifyFilters.DirectoryName;
    oFileSystemWatcher.Filter = "*.txt";
 
    // Adicionar os manipuladores de evento.
    oFileSystemWatcher.Created += new FileSystemEventHandler(OnCreated);
 
    // Iniciar a monitoracao.
    oFileSystemWatcher.EnableRaisingEvents = true;
 
    // Aguardar que o usuario finalize o programa.
    Console.WriteLine("Press \'q\' to quit the sample.");
    while(Console.Read()!='q');
}
 
// O manipulador de eventos
private static void OnCreated(object source, FileSystemEventArgs e)
{
    Console.WriteLine("File: " +  e.FullPath + " " + e.ChangeType);
}

Por favor notar: o evento Created não garante que outra aplicação ou usuário acabaram de escrever o arquivo. Por exemplo, muitas vezes um servidor necessita esperar que um usuário carregue um arquivo em uma pasta específica. O evento Created será levantado assim que os usuários iniciem a carga do arquivo, porém o servidor terá que esperar até que o processo de copy/upload termine. Não existe nenhum método ideal de que eu tenha conhecimento, que garanta a conclusão da transferência. Podemos contornar este problema, esperando até que possa ser realizada uma operação de abertura nesse arquivo. Enquanto está rodando o copy/upload a abertura falhará.

A função funciona somente com aplicações de console (pois tem Console.Writelines). Para o seu uso, modificá-la como for necessário.

Truque 4: Humanizando sua aplicação

Não sei sobre você, porém sempre me esforcei para dar aos usuários da aplicação uma ajuda extra quando necessário. A Microsoft fornece com esta finalidade, um componente COM realmente interessante chamado MS Agent. Ele pode mostrar um boneco amigável para nossa aplicação - para ler texto, fazer animações e adicionar alguma vida a sua aplicação!

(1) adicione o componente COM do MS Agent no toolbox VS.NET, clicando no menu do Visual Studio Tools > Add/remove toolbox itens > COM Components. Marcar `Microsoft Agent Control 2.0’ e clicar OK.

(2) o controle do agente será mostrado agora sob a aba ‘components` no VS toolbox. Nas aplicações Windows Form, arraste-o e coloque-o no formulário. O componente será adicionado ao formulário e veremos o seguinte membro no mesmo:

public class Form1 : System.Windows.Forms.Form
{
  private AxAgentObjects.AxAgent axAgent1;

 Agora, adicionamos manualmente o seguinte membro imediatamente depois do código:

private AgentObjects.IAgentCtlCharacter speaker;

(3) Temos agora a infra-estrutura do agente no lugar e também temos o objeto alto falante. Em um evento apropriado, tal como o form_load ou o button_click, adicionr o seguinte código:

try
{
    this.axAgent1.Characters.Load("merlin" , "merlin.acs");
    this.speaker = this.axAgent1.Characters["merlin"];
    this.speaker.Show(null);
    this.speaker.MoveTo(800, 600, null);
    this.speaker.Play("Explain");
    this.speaker.Speak("Give some text here for me to talk...", null);
}
catch
{
    MessageBox.Show("Invalid charater");
}

Notar que é melhor carregar o agente uma única vez, normalmente quando o formulário for carregado e então, utilizá-lo em vários eventos conforme desejado.

(4) isso é tudo. Executar o programa e ver o agente em ação. Caso não tenha os arquivos do agente instalados, visitar o seguinte link para fazer o download dos arquivos do agente e, caso requerido, os motores TTS para as linguagens desejadas: http://www.microsoft.com/products/msagent/downloads.

Notar, por favor, que utilizar os Agents somente faz sentido para as aplicações corretas e se for utilizado corretamente. Se utilizado com uma aplicação errada ou de uma maneira errada, pode ser muito irritante para os usuários.

Truque 5: Invocar utilitários a partir do seu programa

Às vezes executar um arquivo batch ou um programa utilitário com argumentos de linha de comando, é tão simples quanto escrever nosso próprio código. Vamos supor, por exemplo, que o programa gera um relatório no formato MS Excel, podemos utilizar o código abaixo para abrir o arquivo recentemente gerado com o Excel/p>

System.Diagnostics.Process.Start(
@"c:\program files\microsoft office\excel.exe", @"c:\myFile.xls");

Utilizando o código

Deliberadamente, não anexamos os exemplos do código e os arquivos do projeto. Pois a idéia é manter o código tão conciso e específico da tarefa quanto possível. Tudo o que é necessário fazer é copiar-colar as funções de exemplo diretamente no seu código e iniciar sua utilização.

Finalizando

Compilamos esta lista enquanto estávamos trabalhando pela primeira vez em um produto servidor no .NET C#, portanto devem existir pequenas inconsistências. Por favor, me corrijam caso tenham melhores soluções.

Espero que tenham apreciado este artigo e que utilizem algumas ideias dele nos seus projetos. Boa sorte e meus mais sinceros agradecimentos!