Escolar Documentos
Profissional Documentos
Cultura Documentos
www.marcelosincic.com.br
Pgina 1 de 44
Ol, Criei estas apostilas a mais de 5 anos e atualizei uma srie delas com alguns dados adicionais. Muitas partes desta apostila est desatualizada, mas servir para quem quer tirar uma dvida ou aprender sobre .Net e as outras tecnologias.
Perfil Microsoft: https://www.mcpvirtualbusinesscard.com/VBCServer/msincic/profile Marcelo Sincic trabalha com informtica desde 1988. Durante anos trabalhou com desenvolvimento (iniciando com Dbase III e Clipper S'87) e com redes (Novell 2.0 e Lantastic). Hoje atua como consultor e instrutor para diversos parceiros e clientes Microsoft. Recebeu em abril de 2009 o prmio Latin American MCT Awards no MCT Summit 2009, um prmio entregue a apenas 5 instrutores de toda a Amrica Latina (http://www.marcelosincic.eti.br/Blog/post/Microsoft-MCT-Awards-AmericaLatina.aspx). Recebeu em setembro de 2009 o prmio IT HERO da equipe Microsoft Technet Brasil em reconhecimento a projeto desenvolvido (http://www.marcelosincic.eti.br/Blog/post/IT-Hero-Microsoft-TechNet.aspx). Em Novembro de 2009 recebeu novamente um premio do programa IT Hero agora na categoria de especialistas (http://www.marcelosincic.eti.br/Blog/post/TechNet-IT-Hero-Especialista-Selecionado-o-nosso-projeto-de-OCS2007.aspx). Acumula por 5 vezes certificaes com o ttulo Charter Member, indicando estar entre os primeiros do mundo a se certificarem profissionalmente em Windows 2008 e Windows 7.
Possui diversas certificaes oficiais de TI: MCITP - Microsoft Certified IT Professional Database Administrator SQL Server 2008 MCITP - Microsoft Certified IT Professional Database Administrator SQL Server 2005 MCITP - Microsoft Certified IT Professional Windows Server 2008 Admin MCITP - Microsoft Certified IT Professional Enterprise Administrator Windows 7 Charter Member MCITP - Microsoft Certified IT Professional Enterprise Support Technical MCPD - Microsoft Certified Professional Developer: Web Applications MCTS - Microsoft Certified Technology Specialist: Windows 7 Charter Member MCTS - Microsoft Certified Technology Specialist: Windows Mobile 6. Charter Member MCTS - Microsoft Certified Technology Specialist: Windows 2008 Active Directory Charter Member MCTS - Microsoft Certified Technology Specialist: Windows 2008 Networking Charter Member MCTS - Microsoft Certified Technology Specialist: System Center Configuration Manager MCTS - Microsoft Certified Technology Specialist: System Center Operations Manager MCTS - Microsoft Certified Technology Specialist: Exchange 2007 MCTS - Microsoft Certified Technology Specialist: Windows Sharepoint Services 3.0 MCTS - Microsoft Certified Technology Specialist: SQL Server 2008 MCTS - Microsoft Certified Technology Specialist: .NET Framework 3.5, ASP.NET Applications MCTS - Microsoft Certified Technology Specialist: SQL Server 2005 MCTS - Microsoft Certified Technology Specialist: Windows Vista MCTS - Microsoft Certified Technology Specialist: .NET Famework 2.0 MCDBA Microsoft Certified Database Administrator (SQL Server 2000/OLAP/BI) MCAD Microsoft Certified Application Developer .NET MCSA 2000 Microsoft Certified System Administrator Windows 2000 MCSA 2003 Microsoft Certified System Administrator Windows 2003 Microsoft Small and Medium Business Specialist MCP Visual Basic e ASP MCT Microsoft Certified Trainer SUN Java Trainer Java Core Trainer Approved IBM Certified System Administrator Lotus Domino 6.0/6.5
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 2 de 44
Introduo ao Ambiente Gerenciado ............................................................3 1.1 1.2 Comparao com Ambiente No Gerenciado (COM) ...........................3 Garbage Collector....................................................................................3 Class Library ............................................................................................5 Windows Control Library ........................................................................6 Console Application ................................................................................8 Criao do Servio ..................................................................................9 Installer ................................................................................................... 10 Instalando o Servio no Windows........................................................ 10 Retornando Configuraes .................................................................. 12 Utilizando Converses e Comparaes .............................................. 12 Aplicao SingleThread ........................................................................ 14
Threading ...................................................................................................... 14 5.1 5.2 Aplicao MultiThread .......................................................................... 15 5.2.1 Sincronizao de Threads ................................................................ 16
6 7
Serializao ................................................................................................... 17 Versionamento .............................................................................................. 19 7.1 7.2 7.3 Global Assemblie Cache ....................................................................... 19 Strong Name .......................................................................................... 21 Registrando Verses ............................................................................. 22 Configurao de Segurana ................................................................. 24
Segurana ..................................................................................................... 24 8.1 8.2 Certificao Digital ................................................................................ 30 8.2.1 Criptografia de Dados ....................................................................... 30 8.2.2 Utilizando Assinatura Digital ............................................................. 30
Servios de Rede .......................................................................................... 35 9.1 Criando e Definindo um Servidor Socket ............................................ 35 9.1.1 Recebendo Mensagens .................................................................... 35 9.1.2 Respondendo Mensagens ................................................................ 37 9.2 Criando um Cliente Socket ................................................................... 38 Componentes Avanados do VS 2003 .................................................... 39
Reproduo e distribuio livre
10
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 3 de 44
Esta tabela no traz todas as diferenas que existem entre o COM e o .NET mas exemplifica muito bem as principais. Podemos notar que o COM uma tecnologia mais bem fundada no ambiente Microsoft, com servidores e servios implementados que facilitam a administrao em ambientes de redes corporativas. Por outro lado o .NET, por ser voltado a web, possui uma integrao, facilidade de desenvolvimento com ferramentas avanadas e rpido deployment da aplicao. No caso de uma aplicao distribuda o .NET possui tres solues que podem ser utilizadas, e a tabela a seguir mostra as principais diferenas entre elas:
Requisito Autenticao Criptografia Manipulao de Objetos Winsock No suporta No suporta No possui (trafega ASCII) Remmoting Manual pelo proxy Manual pelo proxy Suportado Web Services Suportado pelo IIS Suportado pelo IIS Depende da linguagem e do objeto 19 seg. na 1a. execuo 3 seg. nas seguintes Simples Enterprise Services
Performance 7 seg. na 1a. execuo 1,5 seg (envio e retorno simples) 1,5 seg. nas seguintes Desenvolvimento Complexo Mdio Abrangido em Mdulo 9 Enterprise Services Nota: Os dados abaixo tem como base componentes escritos em C# com .NET
Verso: 1.1
www.marcelosincic.com.br
Pgina 4 de 44
Em sistema desenvolvidos no COM era necessrio o programador manualmente desinstanciar e destruir o objeto criado. No framework no mais necessrio j que o GC cuidar desta tarefa. Ao desinstanciar um objeto este no instantaneamente destrudo. O processo do GC relativamente consumidor de recursos, uma vez que ele precisa consultar a tabela de objetos e verificar quais esto realmente sem uso e podem ser destrudos. O GC s executado quando o sistema est necessitando de recursos, ento o CLR chama o GC para este limpar e liberar memria. Mas em algumas situao, como por exemplo, utilizarmos um grande dataset e aps terminar o uso sabemos que outro grande dataset ir ser utilizado, podemos forar a execuo do GC. Podemos chamar o GC diretamente por utilizar a seguinte instruo:
MessageBox.Show(System.GC.GetTotalMemory(true).ToString()); GC.Collect(); MessageBox.Show(System.GC.GetTotalMemory(true).ToString());
Note que as mensagens so apenas para retornar a memria total antes e depois da chamada do GC para coletar memria. Apesar do recurso estar disponvel no recomendado forar o GC por corrermos o risco de aplicaes que no esto utilizando o componente no momento mas esto referenciados perderem a estabilidade.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 5 de 44
2 Criao de Componentes
Podemos criar diversos diferentes tipos de componentes no .NET Framework, sendo criados conforme os modelos existentes no VS:
Tipo Class Library Windows Service Windows Control Library Console Application Descrio Componentes dll encapsulando classes para utilizao em qualquer tipo de aplicao Servios que rodam em background, gerenciados pelo Windows Controle para utilizar em diversos formulrios para interao Aplicao de linha de comando Visual
Aps referenciar um componente para utilizar suas classes utilizamos o mtodo normal de instanciamento, ou seja: Como exemplo, podemos imaginar uma classe com funes matemticas que so utilizadas em diversos aplicativos diferentes.
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 6 de 44
Uma das solues seria copiar este arquivo cs ou vb para todos os projetos que fizermos, mas uma alterao ou correo teriamos que recompilar todos os aplicativos. Neste caso uma dll utilizada por todos os sistemas teramos a vantagem de apenas na recompilao desta todos os aplicativos estariam tambm atualizados, pois na verdade apenas utilizam o componente.
Como um controle inserido em outros formulrios da aplicao, precisamos criar propriedades e adaptar ao ambiente em que ele ser includo. Como primeiro passo utilizamos o evento resize do formulrio para alterar o tamanho da caixa de texto:
private void CEP_Resize(object sender, System.EventArgs e) { txtCEP.Width = this.Width; txtCEP.Height = this.Height; }
Aps compilar o projeto podemos inserir um novo projeto na mesma soluo por clicar no solution e na opo add incluir um projeto do tipo windows application que far uso do controle que est sendo testado. Para colocar o controle na barra de ferramentas deve-se primeiro compilar o projeto e clicando na barra com o boto direito escolher add/remove itens, encontrar a localizao fsica do disco onde a dll do controle foi compilada e aparecer na barra o cone do controle.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 7 de 44
Basta arrastar como qualquer outro item da barra de ferramentas para que funcione, como a figura abaixo demonstra, incluindo j redimensionado como o cdigo anterior:
Agora precisamos refinar as propriedades do controle, uma vez que ele possui apenas as propriedades comuns a todos os controles, e precisamos criar a propriedade para alterar a fonte, a cor de fundo e o texto que est digitado. Portanto, iremos criar as propriedades devidas conforme o cdigo abaixo:
//Propriedade para manipular o texto da caixa public string Texto { get { return txtCEP.Text; } set { txtCEP.Text = value; } } //Propriedade para manipular a cor de fundo public Color CorDeFundo { get { return txtCEP.BackColor; } set { txtCEP.BackColor = value; } } //Propriedade para manipular a fonte do texto public Font Fonte { get { return txtCEP.Font; } set { txtCEP.Font = value; } } //Propriedade para manipular a cor do texto public Color CorDoTexto { get { return txtCEP.ForeColor; } set { txtCEP.ForeColor = value; } }
Note que as propriedades que retornam dados especiais como fonte e cores no foi utilizado um CTS e sim um objeto que automaticamente se transformar em caixa de dilogo quando for utilizado em uma aplicao. O resultado pode ser visto na figura com a tela abaixo:
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 8 de 44
Note que conseguimos ter uma interao com o usurio no grfica, mas em modo texto, onde o digitou o numero de repeties desejadas. Ao utilizar uma aplicao de console no podemos usar mensagens grficas, portanto para pedir dados utilizamos o readline ou o read e para mostrar os dados o writeline ou write.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 9 de 44
3 Servios do Windows
Um servio do Windows pode ser utilizado para diversas funes, como por exemplo, monitorar o uso do servio de processamento, para gerar relatrios em perodos pr-programados entre outras funes. A vantagem do servio sobre outros tipos de aplicaes que servios no precisam ser inicializados nem gerenciados. Quem inicializa um servio o prprio sistema operacional do Windows e este roda como parte do sistema operacional, sem criar interfaces ou estar vulnervel ao close por parte do usurio final. Como exemplo para um servio utilizemos o servio que cria uma conexo com o servidor de banco de dados e verifica quanto tempo demorou para responder com uma instruo DML, e esta informao ser guardada em um arquivo texto.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 10 de 44
Note no cdigo os eventos de inicializao e finalizao que permitem utilizar o servio e identificar sua operao. DICA: Cuidado que existem dois timers no VS, um serve apenas para Windows Forms. Criamos um novo mtodo permitindo a gravao do texto em um arquivo, pois como esta funo seria utilizada em diversos lugares, reaproveitamos a lgica. Agora que nosso servio j tem o cdigo necessrio para a operao desejada, precisa configura-lo no sistema operacional.
3.2 Installer
Um servio do sistema operacional diferente de um programa comum por questo da segurana e do local onde ficar. Um programa comum se aloca em um diretrio qualquer e executado com o direito do usurio que est logado no momento. Servios no so executados por um usurio comum, mas por um usurio do sistema operacional ou do domnio. Por isso precisamos incluir no servio os installer, componentes que definem as propriedades que o sistema operacional exige e as funcionalidades para rodar como parte do sistema operacional e contexto de segurana. Para incluir os installer basta clicar com o boto direito no servio e escolher a opo Add Installer, que resultar na tela abaixo:
Nas propriedades do instalador podemos definir o tipo de inicializao, se automtico ou manual, o nome do servio e a descrio que ir aparecer no Service Manager do sistema operacional.
Verso: 1.1
www.marcelosincic.com.br
Pgina 11 de 44
Sua sintaxe simples, bastando indicar o nome do arquivo e ser aberto uma janela para ser colocado o nome e a senha do usurio que executar o servio, como a tela abaixo:
A conta que ser utilizada deve ser administradora da mquina local onde o servio est sendo instalado ou ento ter o direito de ser utilizada para servios. Mas independente de utilizar o administrador da mquina ou outra conta, esta precisa ter acesso ao servidor onde o MSSQL est para poder testar a conexo. Aps a execuo e instalao do servio podemos pelo aplicativo services do sistema operacional ver o servio na lista e inici-lo como as telas abaixo demonstram:
Ao clicar no boto de iniciar o servio comeou sua operao criando o log no disco. Para desinstalar um servio, pare pelo service manager e utilize o comando:
installutil nomedoservico.exe u
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 12 de 44
4 Globalizao
O componente de globalizao importante e muito til para verificar as configuraes do cliente, bem como converses e outras funes.
Note na primeira instruo o cdigo pt de portugus e br para Brasil. Na segunda instruo o retorno o cdigo da moeda e a segunda instruo o formato de data utilizado:
dddd, d' de 'MMMM' de 'yyyy HH:mm:ss
Utilizando o globalization criamos um objeto especifico para comparao e utilizamos fazendo a pesquisa. Note que na utilizao do compare escolhemos a opo ignoresymbols que so acentos e caracteres especiais. Tambm possvel mandar ignorar espaos, maisculos, minsculos, hifenizao e outros. A utilizao do globalization grande para conseguir datas em qualquer formato ou pais independente da utilizada localmente. O cdigo abaixo demonstra como a data pode ser mostrada nos formatos brasileiro e americano:
System.Globalization.CultureInfo Brasileiro = new System.Globalization.CultureInfo("pt-br"); System.Globalization.CultureInfo Americano = new System.Globalization.CultureInfo("en-us"); DateTime Hoje = DateTime.Now; Console.WriteLine(Hoje.ToString(Brasileiro)); Console.WriteLine(Hoje.ToString(Americano));
O primeiro objeto criada, chamado de americano, utiliza a cultura en-us e o segundo objeto, chamado de brasileiro, utilizou a cultura pt-br que tambm a cultura nativa na estao utilizada. Nas converses para string foram utilizados os objetos de cultura e conseguimos o retorno no formato deseja. O resultado na execuo acima foi:
18/8/2004 09:42:34 8/18/2004 9:42:34 AM
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 13 de 44
Esta funo podemos utilizar quando trazemos dados do banco de dados, que trabalha no formato ansi (ano-ms-dia) e o retorno precisa estar no formato brasileiro (dia/ms/ano).
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 14 de 44
5 Threading
Aplicaes executadas trabalham automaticamente no modo singlethread. Este modelo de execuo significa que quando executamos um mtodo devemos esperar ele acabar para a execuo continuar. O modelo multithread ocorre quando um mtodo executa outro e no aguarda o termino, apenas inicia a execuo e continua suas instrues. A grande diferena entre o singlethread e o multithread o nvel de controle programtico. No modelo single no necessrio nenhuma linha de cdigo, uma vez que a lgica do programa inicia um mtodo e fica esperando este mtodo acontecer, no precisando perguntar quando este j terminou e o resultado. No modelo multi necessrio codificar o controle, j que ao chamar o mtodo o programa continuar sua execuo sem o resultado ou retorno, incluindo caso ocorrerem erros neste thread, j que o try...catch no estar controlando a execuo da thread.
Ao rodar o cdigo acima a aplicao ir travar, pois entrar em um loop continuo que o impede de outras funes. Para resolver este primeiro problema utilizamos uma instruo de sincronizao que dever ser colocada logo abaixo da funo a ser sincronizada, no caso de nosso exemplo, abaixo da linha que faz a soma incremental:
Application.DoEvents();
Agora o valor aparece corretamente nas caixas de texto, mas a aplicao se comporta de um modo estranho, ao clicar nos botes o contador pra ou a funo no acontece. Colocando o mesmo cdigo acima no segundo boto, mas alterando a segunda caixa de texto, notamos que quando um contador est executando, o outro fica parado.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 15 de 44
Note no primeiro destaque a criao de dois objetos derivados da classe theading, cada um relativo ao contador do boto clicado. No segundo bloco em destaque vemos a instancia do thead que feita derivando de um objeto theadingstart mais o nome do mtodo que ser chamado. At este momento as threads j existem mas no esto em execuo. No bloco destacado abaixo vemos uma condio onde testado o estado da thread, e caso esteja como running retornamos ao usurio uma mensagem para aviso. Quando a thread no est em execuo utilizamos o mtodo start para inicializa-la. Uma instancia de thread tambm possui os mtodos suspend, resume e abort para respecitivamente, pausar, reiniciar e parar o processo.
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 16 de 44
Uma importante propriedade das threads priority onde podemos definir quando em execuo simultnea qual processo recebe mais poder do que outro em execuo, sendo este controlado pelo sistema operacional. O cdigo abaixo demonstra como a primeira thread est prioridade menor que a segunda:
Contador1.Priority = System.Threading.ThreadPriority.Normal; Contador2.Priority = System.Threading.ThreadPriority.AboveNormal;
5.2.1 Sincronizao de Threads Um problema tpico quando utilizamos o modelo multithread quando temos mais de uam tarefa sendo realizada ao mesmo tempo, mas que os resultados dependem entre si. A forma mais comum de sincronizar trs processos simultneos utilizar um timer que verifique a propriedade threadstate at que os trs processos acusem stopped. Outra forma utilizando tambm um timer e trs variveis indicativas, onde ao invs de verificar o estado do processo, verificamos o valor da varivel que alterada dentro da thread quando termina seu processo. Ainda outra importante questo quando mltiplos processos simultneos e dependentes esto em execuo o recurso de poder mandar um determinado processo que dependa de um outro ficar pausado enquanto o outro processo executa. Para pausar basta colocar o nome da instancia da thread e utilizar o mtodo Suspend.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 17 de 44
6 Serializao
O processo chamado de serializao transformar um objeto qualquer do .NET Framework em formato universal. A este formato universal chamamos de stream, que um array de bytes. A serializao utilizada quando temos uma imagem, um array, uma classe ou outros tipos de dados que no so nativos ao sistema operacional e o transformamos em uma seqncia de bytes hexadecimal. No cdigo abaixo criamos um array com uma lista de clientes, serializamos o array inteiro, sem precisar concatenar string ou similar e recebemos em outra funo:
private void Transforma() { object[,] Clientes = new object[3,2]; Clientes[0,0]="Joao"; Clientes[0,1]="1234-5678"; Clientes[1,0]="Joaquim"; Clientes[1,1]="8765-4321"; Clientes[2,0]="Maria"; Clientes[2,1]="5678-1234"; System.IO.MemoryStream Tabela = new System.IO.MemoryStream(); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Serializa = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); Serializa.Serialize(Tabela, Clientes); RecebeStream(Tabela); } private void RecebeStream(System.IO.MemoryStream Serializado) { Serializado.Position = 0; System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Deserializa = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); object[,] Dados = (object[,]) Deserializa.Deserialize(Serializado); foreach(object Cliente in Dados) { Console.WriteLine(Cliente.ToString()); } }
No primeiro bloco do programa criamos um array com trs clientes contendo nome e telefone. Todo array um objeto binrio, portanto no pode trafegar em rede em seu formato nativo, ainda mais porque cada plataforma e linguagem possui diferente forma de representar o array. Na seqncia foi utilizada a classe Serialization.Formatters.Binary.BinaryFormatter que como o prprio nome diz, a classe que formata um dado binrio serializando em hexadecimal. Para termos uma idia do que o array em hexadecimal, o cdigo abaixo transforma o dado serializado em uma cadeia de string:
Tabela.Position=0; string Texto=""; while(true) { int Byte = Tabela.ReadByte(); if(Byte==-1) break; else Texto += Byte.ToString("X"); } Console.WriteLine(Texto); 01000FFFFFFFF1000000071000220003000200026200044A6F616F630009313233342D353637386400074A6F617175696D 650009383736352D343332316600054D61726961670009353637382D31323334B
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 18 de 44
Note que o cdigo transforma cada byte do memorystream serializado em um hexadecimal, gerando a string acima. Veja que o bloco destacado o nome e o telefone do cliente Joaquim. Voltando ao cdigo anterior, notamos que foi criado um objeto memorystream que o array de bytes para receber o objeto array serializado. Na utilizao do mtodo serialize utilizamos o nome do stream que foi criado e no segundo parmetro o array a ser serializado. No mtodo que deserializa aps referenciar a classe que faz a operao usamos o mtodo deserialize com o nome do memorystream, e convertemos o resultado da operao em um array de objetos chamado dados. Na ultima parte do cdigo navegamos no array normalmente. Este exemplo mostra como a serializao e deserializao simples por no necessitar mais do que quatro linhas de cdigo para ser implementado.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 19 de 44
7 Versionamento
No .NET possvel trabalhar com verses de um mesmo componentes, uma vez que uma funcionalidade do componente pode ser alterada e isto exige conhecimentos de strong name que ser abordado a frente. A necessidade do versionamento surge quando em uma primeira anlise foi criado um componente que contem, por exemplo, quatro mtodos e agora o componente foi alterado para 7 mtodos. As aplicaes que utilizavam o componente anterior precisam continuar acessando o componente original, mas as novas aplicaes devem poder acessar o novo componente. Uma das formas de fazer o versionamento copiar a dll utilizada na aplicao junto com ela, mas neste caso quando a manuteno for feita no fonte precisaremos copiar em todos os diretrios de aplicao j existentes.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 20 de 44
Veja na figura 6 que temos diversos assemblies em diferentes verses. A grande vantagem do GAC que ao executar um sistema o CLR do .NET primeiro faz a pesquisa do componente solicitado no GAC e caso no encontre utiliza a dll que estiver no diretrio local da aplicao. Como este processo procura primeiro no GAC, se nossos assemblies estiver nele no precisamos ter a copia das dlls utilizadas para a aplicao copiadas. Este processo aumenta a performance pois o GAC s compila uma vez o componente e tambm a manuteno, uma vez que se houverem 10 aplicaes utilizando uma classe, na verdade todas esto utilizando um nico assemblie. Existem duas forma de incluir um novo assemblie no GAC, a primeira por utilizar a ferramenta de configurao do framework e a outra utilizar o aplicativo de linha de comando gacutil. Este aplicativo muito simples, com as seguintes sintaxes bsicas:
Linha de comando gacutil ldl gacutil /u gacutil /i gacutil /f Funcionalidade Lista os assemblies que esto no GAC (no os do prprio framework) Desinstala um assemblie Instala um assemblie Fora a reinstalao de um assemblie
Quando falamos no GAC tambm til entendermos cdigo nativo. Por padro as aplicaes criadas no VS 2003 esto apenas no IL, ou seja, na linguagem interpretada. Na primeira execuo feita uma compilao pelo componente MSIL to Native Code do framework que transforma o cdigo IL em cdigo nativo de CLR, processo chamado de JIT (Just-In-Time compilation). DICA: Note que estamos falando de cdigo nativo de CLR e no cdigo nativo de mquina. Mas podemos ganhar performance por deixar este componente j compilado em cdigo nativo, e para isso utilizamos o aplicativo ngen. A sintaxe do ngen simples, apenas informando na seqncia o nome do assemblie, que pode ser dll ou exe.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 21 de 44
A vantagem de transformar em cdigo nativo e um ganho de performance considervel na primeira execuo, uma vez que no ser necessrio o framework criar uma compilao pelo JIT. Mas a desvantagem de criar cdigo nativo que em aplicaes web criada uma dll compilada na primeira execuo em um diretrio especifico e a dll da aplicao pode ser sobreposta a qualquer momento. Quando utilizamos nativo, no necessrio criar a dll temporria, portanto se precisar fazer manuteno na aplicao web no ser possvel pelo motivo do assemblie estar em uso pelo servidor. Para um assemblie poder ser registrado no GAC ele precisa ter um strong name.
Veja que foi criado o arquivo e agora podemos assinar uma aplicao utilizando esta chave. Para isso alteramos o arquivo AssemblyInfo que cada aplicao possui. Abaixo temos o exemplo do arquivo AssemblyInfo do controle grfico CEP:
using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.*")]
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 22 de 44
Note que o nome do arquivo gerado pelo sn est referenciado para ser utilizado na aplicao para este estar devidamente assinado. No mdulo de segurana veremos que necessrio que cada aplicao esteja com um strong name registrado para podermos fazer os controles de acesso.
Neste caso registramos o componente na verso 1.0 conforme o arquivo config no tpico anterior. Alterando a verso do componente para 1.1 como o config abaixo podemos versionar o componente: Compilamos o componente e utilizamos novamente o utilitrio do GAC. Veja o resultado no utilitrio de configurao do framework abaixo:
[assembly: AssemblyVersion("1.1.*")]
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 23 de 44
Note que o componente CEP aparece duas vezes, como verso 1.0.1691 e 1.1.1692, como desejvamos. Importante ressaltar que para manter o versionamento, antes de recompilar o componente foi feita uma copia do arquivo cep.ddl para outro diretrio e o utilitrio de registro da verso 1.0 foi feita com esta cpia, uma vez que no podamos sobrepor a nova verso. Veja na tela de seleo do VS 2003 que agora podemos escolher entre as verses:
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 24 de 44
8 Segurana
A segurana de aplicaes escritas em .NET so muito melhoradas em relao as aplicaes escritas em VB6, VC++, Delphi e outras. Nestas anteriores linguagens o software aps instalado no cliente rodava no contexto do usurio corrente, ou seja, se o usurio era administrador e tinha acesso a todos os recursos da mquina, conseqentemente o programa tinha os acessos a todos os recursos da mquina. Como esta caracterstica, chamada de execuo em contexto, era muito simples desenvolver aplicaes que maliciosamente roubavam dados da maquina ou se utilizam de servios desta para explorar dados. Nas aplicaes .NET isto no mais pode acontecer a menos que o usurio o permita, pois agora temos uma configurao para a segurana do CLR, definindo que programa pode fazer o que.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 25 de 44
Podemos ver a mesma aplicao acusando a falta de permisso para gravar dados no disco, efeito desejado quando uma aplicao tenta sem o consentimento do usurio fazer o acesso local. Vamos garantir a permisso necessrio que a aplicao deseja rodando novamente o configuration do framework, mas antes precisamos alterar o arquivo config da aplicao e atribuir o certificado de strong name criado anteriormente nesta aplicao. Feito isto, segue as telas configurando a permisso necessria baseada no strong name.
[assembly: AssemblyKeyFile(@"c:\MinhaChave.key")]
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 26 de 44
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 27 de 44
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 28 de 44
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 29 de 44
Como as telas acima demonstram, criamos primeiro um grupo de segurana onde foi definido que acesso a disco no diretrio desejado era permitido, bem como interface visual com o usurio e uso do clipboard. Na seqncia foi criado um grupo de programas, sendo que a dll cep foi utilizada para extrair o strong name identificador de nossas aplicaes. A este grupo de programas, ou cdigos, foi atribudo o grupo de segurana que criamos, permitindo agora que o programa tenha acesso ao diretrio especificado. Como teste podemos alterar o diretrio onde o programa gravava o arquivo de log e ao executar ocorrer um erro, pois o novo diretrio deveria ser includo no grupo de segurana.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 30 de 44
Verso: 1.1
www.marcelosincic.com.br
Pgina 31 de 44
Um exemplo de programas assinados quando acessamos um site com flash e este mostra uma mensagem informando que a Macromedia assinou digitalmente aquele componente e que este seguro. Para gerar o certificado de exemplo provido pelo VS 2003 utilizamos o aplicativo makecert conforme a figura abaixo.
Aps a criao do certificado configuramos o assemblie para utiliza-lo, e isto feito com o aplicativo Signcode.exe, que conforme as figuras abaixo pode-se ver o passo a passo.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 32 de 44
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 33 de 44
Figura 33 Finalizao
Pronto, agora seu programa esta assinado digitalmente como sendo da Joe Software, e nas figuras abaixo temos as propriedades da dll assinada.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 34 de 44
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 35 de 44
9 Servios de Rede
Quando utilizamos o protocolo TCP/IP possumos o endereo do computador (chamado de host) que formado pelos quatro octetos do IP, ou seja, 200.150.200.100, 10.0.2.1, etc. Um mesmo host pode conter mltiplos servios e os utilizamos por identificar a porta de dois octetos, variando de 1 a 65535. Cada servio assume uma determinada porta de endereo TCP ou UDP, sendo a diferena entre estes dois que TCP so portas de transporte para dados com datagrama pr-definido, enquanto UDP permite a criao do datagrama customizado. Algumas das portas mais conhecidas esto listadas abaixo:
Porta 21 25 80 110 143 389 443 1433 Servio FTP Transferncia de arquivos binrios pela internet SMTP Envio e recebimento de email por servidor HTTP Servidor web POP3 Recebimento de email pelo cliente IMAP4 Recebimento de email com sincronizao de dados LDAP Consulta ao servio de usurios Active Directory e outros HTTPS Servidor web com criptografia Microsoft SQL Server
Portanto, para utilizar comunicao entre computadores precisamos aprender a receber e enviar dados pelas portas. A estes componentes que trafegam dados em rede chamamos de sockets.
bom lembrar que a comunicao por socket no utiliza criptografia e mensagem padronizada, permitindo trafegar bytes e no binrios. Portanto, para utilizar de forma segura necessrio utilizar alguma forma de criptografia personalizada ou utilizar as classes de criptografia do prprio sistema operacional chamado de IPSec (IP Secure). Quanto a mensagem preciso padronizar o formato da mensagem, podendo ser uma classe serializada, uma string posicional ou delimitada por marcadores, sendo este ultimo o mais utilizado. 9.1.1 Recebendo Mensagens Para exemplificar a utilizao da comunicao, criamos um formulrio com uma caixa de texto para digitar a porta, um boto para processar e uma lista para mostrar os passos da comunicao. O cdigo abaixo apenas cria um objeto para receber os dados e no para responder, o que veremos adiante. O cdigo abaixo est no boto:
lstMensagens.Items.Add("Abrindo porta " + txtPorta.Text); //Abre a porta digitada como "ouvidor" Servidor = new System.Net.Sockets.TcpListener(int.Parse(txtPorta.Text)); lstMensagens.Items.Add("Esperando cliente...");
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 36 de 44
Para fazer o teste com os dados podemos utilizar o aplicativo telnet. Como exemplo, ativamos o programa de comunicao digitando 15000 na porta e na linha de comando do sistema operacional digitamos: Para terminar a sesso basta tecla ENTER pois este equivalente a 13 em byte, o que faz a rotina terminar. Avanando o modelo acima podemos traduzir em mensagem o que foi recebido e no fechar o servio a cada conexo. Para alcanar este objetivo iremos transformar o byte em caractere, somar este caractere a uma string e fazer um loop para ao terminar uma conexo abrir outra. O novo cdigo est anexado abaixo:
lstMensagens.Items.Add("Abrindo porta " + txtPorta.Text); //Abre a porta digitada como "ouvidor" Servidor = new System.Net.Sockets.TcpListener(int.Parse(txtPorta.Text)); lstMensagens.Items.Add("Esperando cliente..."); Application.DoEvents(); //Inicia o servio na porta e espera conexo Servidor.Start(); //Loop que segura o servidor bool Termina = false; while(!Termina) { lstMensagens.Items.Add("Cliente conectado."); //Ao receber a conexo cria um objeto cliente System.Net.Sockets.TcpClient Escuta = Servidor.AcceptTcpClient(); //Tempo mximo de 15 segundos de espera Escuta.ReceiveTimeout = 15 * 1000; //Cria um objeto stream para receber os bytes System.Net.Sockets.NetworkStream Dados = Escuta.GetStream(); int Byte = 0; string Mensagem = ""; while(Byte >= 0) {
www.marcelosincic.com.br Reproduo e distribuio livre
Application.DoEvents(); //Inicia o servio na porta e espera conexo Servidor.Start(); lstMensagens.Items.Add("Cliente conectado."); //Ao receber a conexo cria um objeto cliente System.Net.Sockets.TcpClient Escuta = Servidor.AcceptTcpClient(); //Tempo mximo de 15 segundos de espera Escuta.ReceiveTimeout = 15 * 1000; //Cria um objeto stream para receber os bytes System.Net.Sockets.NetworkStream Dados = Escuta.GetStream(); int Byte = 0; while(Byte >= 0) { //Recebe um byte e coloca na lista Byte = Dados.ReadByte(); lstMensagens.Items.Add(Byte.ToString()); Application.DoEvents(); //Byte 13 (ENTER) termina a conexo if(Byte == 13 || Byte == -1) break; } //Fecha o cliente e o servidor Escuta.Close(); Servidor.Stop(); lstMensagens.Items.Add("Conexo fechada.");
Verso: 1.1
www.marcelosincic.com.br
Pgina 37 de 44
//Recebe um byte e coloca na lista Byte = Dados.ReadByte(); //Byte 13 (ENTER) termina a conexo if(Byte == 13 || Byte == -1) break; else Mensagem += (char)Byte; } //Fecha o cliente e o servidor Escuta.Close(); lstMensagens.Items.Add(Mensagem); Application.DoEvents(); if(Mensagem=="fim") Termina = true; } Servidor.Stop(); lstMensagens.Items.Add("Conexo fechada.");
Note que criamos uma varivel para servir de controle, onde quando a mensagem digitada for fim atribudo verdadeiro a varivel e isto encerrar o servidor. Na alterao seguinte transformamos o byte em caractere para somar a uma nica string, que mostrada no final da mensagem. 9.1.2 Respondendo Mensagens No modelo criado no respondemos ao cliente como tendo recebido a mensagem. Agora nosso modelo dever incluir uma mensagem de boas vindas no inicio da conexo e uma mensagem de confirmao ao final da mensagem. Para isso precisamos criar um array de bytes e utilizar o objeto networkstream para enviar este array de bytes ao cliente. O cdigo atualizado com esta funcionalidade segue:
lstMensagens.Items.Add("Abrindo porta " + txtPorta.Text); //Abre a porta digitada como "ouvidor" Servidor = new System.Net.Sockets.TcpListener(int.Parse(txtPorta.Text)); lstMensagens.Items.Add("Esperando cliente..."); Application.DoEvents(); //Inicia o servio na porta e espera conexo Servidor.Start(); //Loop que segura o servidor bool Termina = false; while(!Termina) { lstMensagens.Items.Add("Cliente conectado."); //Ao receber a conexo cria um objeto cliente System.Net.Sockets.TcpClient Escuta = Servidor.AcceptTcpClient(); //Tempo mximo de 15 segundos de espera Escuta.ReceiveTimeout = 15 * 1000; //Cria um objeto stream para receber os bytes System.Net.Sockets.NetworkStream Dados = Escuta.GetStream(); //Transforma uma string em um array de bytes byte[] BoasVindas = System.Text.ASCIIEncoding.ASCII.GetBytes("Seja bem vindo a nosso servidor. Utilize ENTER para finalizar." + (char)13 + (char)10); //Envia os bytes para o cliente Dados.Write(BoasVindas, 0, BoasVindas.Length); //Inicia o loop de recebimento int Byte = 0; string Mensagem = "";
www.marcelosincic.com.br Reproduo e distribuio livre
Verso: 1.1
www.marcelosincic.com.br
Pgina 38 de 44
while(Byte >= 0) { //Recebe um byte e coloca na lista Byte = Dados.ReadByte(); //Byte 13 (ENTER) termina a conexo if(Byte == 13 || Byte == -1) break; else Mensagem += (char)Byte; } //Envia uma mensagem de finalizao e fecha a sesso byte[] Despedida = System.Text.ASCIIEncoding.ASCII.GetBytes((char)13 + (char)10 + "Recebemos seus dados"); Dados.Write(Despedida, 0, Despedida.Length); Dados.Close(); Escuta.Close(); lstMensagens.Items.Add(Mensagem); Application.DoEvents(); if(Mensagem=="fim") Termina = true; } Servidor.Stop(); lstMensagens.Items.Add("Conexo fechada.");
Note que para enviar as mensagens foi necessrio converter a string em seqncia de bytes e envia utilizando o mtodo write do j criado networkstream.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 39 de 44
Note que na janela de propriedades colocamos a categoria do contador que neste exemplo era monitorar um determinado processo, o nome do contador que indica qual processo ou contagem ser analisado e por ultimo o nome da instancia do servidor ou o tipo de contador em outros casos. Em execuo a aplicao trouxe o seguinte resultado:
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 40 de 44
O contador foi ajustado para funcionar a cada segundo e atualizou as caixas de texto com o valor retornando pelo servio de monitorao do Windows. Este componente interessante em aplicaes sensveis ao uso de CPU, por exemplo, uma aplicao que s deve rodar quando a mquina estiver com baixo uso ou ento podemos criar um aplicativo que notifique determinadas situaes ocorridas na mquina.
10.2 EventLog
Os sistemas operacionais Windows NT 4.0 e superiores implementavam um log genrico. Este log est dividido em 3 partes principais: segurana, aplicativos e sistema. As aplicaes, servios e o prprio sistema operacional gravam dados no log sempre que acharem necessrio criar um informativo. Como o log do windows permite a insero do nome do programa, informativo, descrio, grau de importncia e dados binrios, torna-se til quando queremos montar um banco de dados com ocorrncias. Tambm se torna interessante porque alguns sistemas de monitoramento de servidores como o OpenView da HP, o Tivolli da IBM e o MOM da Microsoft utilizam estes eventos do log para avisar administradores. Vamos atualizar a nossa aplicao para que ela gere os dados de performance em uma entrada de eventos do windows. Para isto colocamos no formulrio o componente EventLog e inserimos o seguinte cdigo:
lblCPU.Text = performanceCounter1.NextValue().ToString(); lblMemoria.Text = performanceCounter2.NextValue().ToString(); lblRede.Text = performanceCounter3.NextValue().ToString(); lblSQL.Text = performanceCounter4.NextValue().ToString(); string Mensagem = ""; Mensagem += "CPU = " + lblCPU.Text + (char)13; Mensagem += "Memoria = " + lblMemoria.Text + (char)13;
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 41 de 44
Note que informamos a origem do evento, o tipo (informao) e o cdigo desejado (1000), gerando o evento abaixo no Event Viewer do Windows:
Mensagem += "Rede = " + lblRede.Text + (char)13; Mensagem += "SQL = " + lblSQL.Text; eventLog1.Log = "Application"; eventLog1.Source = "Meu Sistema"; eventLog1.WriteEntry(Mensagem, System.Diagnostics.EventLogEntryType.Information, 1000); eventLog1.Close();
Alem de permitir gravar eventos no log este componente possui a propriedade EventRaisingEvents que quando ligada permite utilizar o evento EntryWriten que a cada novo evento que acontecer no log, independente de qual aplicao gerou, voc poder capturar e tratar. Esta funcionalidade no muito utilizada pois os sistemas de monitoramento relacionados um pouco antes j fazem isso. Mas pode-se utilizar este recurso para monitorar, por exemplo, o evento de queda de comunicao em rede e quando isto acontecer geramos algum tipo de informao para que outros sistemas saibam e ao invs de tentar transmitir o dado guardamos em memria at que a situao se normalize.
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 42 de 44
Neste exemplo estamos gerenciando o SQL Server e o cdigo do boto executa um cdigo onde verifica o estado do servio e inicia ou para este.
private void button1_Click(object sender, System.EventArgs e) { if(serviceController1.Status == System.ServiceProcess.ServiceControllerStatus.Running) serviceController1.Stop(); else serviceController1.Start(); }
10.4 Process
Algumas vezes precisamos abrir e controlar aplicaes fora do framework. Por exemplo, imagine precisar abrir a aplicao wordpad para editar um determinado arquivo texto. Utilize o controle Process e defina em suas propriedades a localizao do programa desejado, como a figura abaixo:
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 43 de 44
Neste caso utilizamos o wordpad e com o cdigo abaixo iniciamos o aplicativo: Para parar o programa podemos utilizar o mtodo kill, ou ento saber dados da aplicao como uso de cpu, uso de memria e diversos outros dados sobre a aplicao que ativamos, inclusive utilizar o evento exit que acontece quando o usurio fechar a aplicao. Imagine uma aplicao a parte de seu sistema para fotografar fotos para crach e o componente chama o programa de fotos e ao fecha-lo o evento exit da sua aplicao l a imagem e faz o devido processamento com a foto.
process1.Start();
www.marcelosincic.com.br
Verso: 1.1
www.marcelosincic.com.br
Pgina 44 de 44
Note que temos quatro eventos que iro permitir com a propriedade nome descobrir o que aconteceu, e especificamente o evento renamed permite saber o nome original e alterado.
www.marcelosincic.com.br