Fevereiro 2006 - Posts

Monad - MSHAnalyser
24-2-2006 21:30
Pois é…esta nova shell tem cada vez mais adeptos  O MSHAnalyser fois construído pelo Karl Prosser e permite usar o Monad a la SQL Server Query Analyser. Um projecto  deveras interessante…
por Luis Abreu | with no comments
Filed under: , ,
Win FX: February CTP
22-2-2006 18:59
Sim, é verdade…já está aí uma nova CTP. Ao que paraece, contém algumas novidades no WPF.
por Luis Abreu | 2 comment(s)
Filed under: ,
C5 Generic Collection
20-2-2006 23:08
O C5 é uma livraria que demonstra como podemos usar generics para expandir as colecções disponibilizadas pela versão 2.0 da plataforma. Parece interessante…
por Luis Abreu | with no comments
Filed under: ,
Monad - histórico de comandos
20-2-2006 22:36

Como seria de esperar, o Monad permite-nos reutilizar os comandos executados previamente já que consegue mantê-los em histórico. Para além de suportar os atalhos tradicionais associados  ao DOSKEY (por exemplo, podemos navegar ao longo dos comandos executados durante uma sessão através das teclas arrow up e arrow down), o monad introduz ainda um conjunto de cdmlets capazes de aumentar as potencialidades fornecidas pelo uso de históricos. Ao longo deste post, vamos falar acerca de dois cmdlets e respectivas potencialidades: get-history e invoke-history.

Quando executado sem atributos, o cmdlet get-history limita-se a apresentar uma lista de comandos executados previamente durante a sessão actual do Monad. Por exemplo, a execução desta instrução na minha máquina retorna o seguinte:

MSH c:\>get-history

Id CommandLine                                                              
  -- -----------                                                              
   1 get-alias ft                                                             
   2 get-alias ft                                                             
   3 get-command *histoty*                                                    
   4 get-command *history*                                                    
   5 get-help get-history                                                     
   6 get-history                                                              
   7 get-history 4                                                            
   8 get-history 4, 5                                                         
   9 get-history 3 -count 2                                                   
  10 get-history
              

Este cmdlet pode receber dois parâmetros: id e count. O primeiro, designado de id, permite definir os ids dos comandos que devem ser retornados. Por exemplo, a instrução seguinte retorna as instruções com os ids 7 e 8:

MSH c:\>get-history -id 7,8

7 get-history 4                                                             
8 get-history 4, 5

Por outro lado, o parâmetro count serve para indicar o número de comandos que deve ser retornado do histórico. O comando seguinte devolve os últimos dois comandos executados na sessão actual:

MSH c:\>get-history -count 2

9 get-history 3 -count 2                                                    
10 get-history
          

Como seria de esperar, podemos combinar ambos os atributos. Por exemplo, a instrução seguinte retorna os 2 últimos comandos a partir do comando 7 (note-se que a contagem é feita de forma decrescente):

MSH c:\>get-history -id 7 -count 2

6 get-history                                                               
7 get-history 4
  

Convém referir que o cmdlet get-history pode devolver um ou mais elementos do tipo HistoryInfo (o cmdlet devolve um array quando têm de devolver mais do que um elemento). Agora que já sabemos o tipo de elemento retornado pelo cmdlet, podemos efectuar um conjunto de operações mais avançadas através do uso de pipes. Por exemplo, a instrução seguinte é capaz de apresentar apenas todos os comandos cuja propriedade CommandName possui o valor get-*:

MSH c:\>get-history | where { $_.CommandName -like “get*”}

Id CommandLine                                                              
  -- -----------                                                              
  17 get-history                                                              
  18 get-history                                                              
  19 get-history                                                              
  20 get-history                                                              
  21 get-history                                                              
  22 get-history > a.txt                                                      
  24 get-help get-history                                                     
  25 get-history -id 7,8                                                      
  26 get-history -count 2                                                     
  27 get-history -id 7 -count 2                                               
  28 get-history -id 7 | get-member                                           
  33 get-history -id 7, 8 | get-member                                        
  40 get-help get-help get-history                                            
  41 get-help get-history
                 

Antes de terminarmos a descrição do cmdlet get-history, temos de referir que, no dia a dia, a utilização deste cmdlet será feita praticamente sempre através do alias history.

O cmdlet invoke-history complementa o cmdlet get-history, já que permite executar uma acção mantida em histórico. Este cmdlet pode receber um parâmetro designado de ID que é usado para identificar o comando que deve voltar a ser executado (a execução deste cmdlet sem nenhum parâmetro repete o último comando executado). O exemplo seguinte ilustra como podemos executar todos os comandos recuperados no exemplo anterior:

MSH c:\>get-history | where { $_.CommandName -like “get*”} | foreach { invoke-command $_.id}

Para finalizar, duas observações: a primeira serve para chamar a atenção para o facto do número de comandos mantidos em histórico ser controlado pela variável $MaximumHistoryCount (que, por predefinição, possui o valor 64). Se quisermos manter mais (ou menos) comandos no buffer do histórico, então temos de atribuir um valor a esta variável. A segunda nota prende-se com o facto do conteúdo do buffer (ou seja, o histórico dos comandos) apenas ser mantido durante a sessão de trabalho (se encerramos o Monad, os comandos executados durante essa sessão são apagados do histórico).

por Luis Abreu | with no comments
Filed under: , ,
FinalReleaseComObject: já não é necessário construir um ciclo em .NET 2.0
20-2-2006 21:11

para libertar todas as referências sobre um objecto COM de forma a conseguir eliminá-lo. Este método vem resolver um dos problemas associados à libertação de referências mantidas sobre um objecto COM na versão 1.X da plataforma.

Now playing: UKTOP40 SINGLES - Juicebox

por Luis Abreu | with no comments
Filed under: ,
Construção de uma mini-framework para suportar a validação
19-2-2006 21:22

Neste fim-de-semana houve, finalmente, algum tempo para escrever mais um artigo para o site. Desta vez, apresento algumas ideias para a construção de uma mini-framework que tenta melhorar o suporte à validação dos dados. Para além disso, o artigo apresenta ainda um novo controlo de validação capaz de efectuar esse tipo de operações através de call-backs síncronos.

por Luis Abreu | with no comments
Filed under: , , ,
Concurrency and Coordination Runtime
18-2-2006 11:46

O channel9  tem um vídeo muito interessante sobre o CCR. No site, a CCR é descrita como:

“The Concurrency and Coordination Runtime (CCR) is a lightweight port-based concurrency library for C# 2.0 developed by George Chrysanthakopoulos in the Advanced Strategies group at Microsoft.”

por Luis Abreu | with no comments
Filed under: ,
Mais informação sobre thread safety
18-2-2006 10:22
Eu devo confessar que, com o passar do tempo (leia-se, posts ), cada vez mais admiro o blog do Joe Duffy! Neste post, ele fornece-nos mais algumas dicas sobre thread safety e apresenta a justificação para o facto do acesso a variáveis cujos tipos sejam superiores ao tamanho do apontador nativo da máquina (sizeof(void*) – ex.: Int64 numa máquina de 32 bits) não serem operações “seguras” do ponto de vista concurrencial.
por Luis Abreu | with no comments
Filed under: ,
Monad - cmdlet get-wmiobject
16-2-2006 21:56

Há muito tempo atrás, prometi falar acerca da utilização de WMI no Monad. Pois bem, é chegada a altura de cumprir essa promessa

O WMI (Windows  Management Instrumentation) foi lançado no final dos anos 90 e tinha como principal objectivo automatizar as tarefas administrativas efectuadas numa máquina. Até ao seu lançamento, essas tarefas administrativas eram feitas sempre (em última análise) através da win 32 API. Na prática, a WMI não é mais do que uma framework de objectos COM que permite o fácil acesso aos recursos expostos pelo SO.

Vamos começar com um exemplo simples: obter a memória existente num computador. Para tal, temos apenas de executar o seguinte comando:

MSH c:\>get-wmiobject Win32_logicalMemoryConfiguration


Name                 totalvirtualmemory totalphysicalmemory  totalpagefilespace
----                 ------------------ -------------------  ------------------
LogicalMemoryCon...             3568752             1047920             2520832

Aqueles que conhecem o WMI já devem ter reconhecido algo familiar: a classe Win32_LogicalMemoryConfiguration. Uma classe WMI representa um recurso de uma máquina (no exemplo anterior, a classe win32_logicalmemoryconfiguration permite aceder á memória existente na máquina onde o comando é executado). A utilização de WMI necessita (quase) sempre de três passos: em primeiro lugar, é necessário estabelecer a ligação ao serviço WMI no computador desejado; em seguida, é necessário obter um (ou mais) objecto(s)  associado(s) ao recurso que contém a informação pretendida. Finalmente, temos de aceder às propriedades dos objectos retornados pelo passo 2 para obtermos os dados pretendidos. Para melhor apreciarmos o Monad, vamos ver as linhas necessárias para obter a memória através de um script vbs:

set wbemServices = GetObject( “winmgmts:\\nome do computador” )
set wbemobjectset = wbemServices.InstancesOf( “Win32_LogicalMemoryConfiguration”)

foreach wbemobject in wbemobjcset
   wscript.echo wbemObject.TotalPhysicalMemory
next

No Monad não temos de escrever tanto para obter o mesmo resultado (algo que, para alguém preguiçoso como eu, é sempre positivo ).

De volta ao WMI, é importante recordar que as classes que representam os recursos são mantidas no interior de vários namespaces. Como seria de esperar, o cmdlet get-wmiobject permite identificar o namespace através da opção -namespace. Já agora, é importante salientar (especialmente para os que, como eu, não costumam usar o WMI) que a classe usada no exemplo anterior está colocada no interior de um namespace -neste caso, a classe encontra-se no interior do namespace root\cimv2 que é usado por predefinição. Portanto, se quiséssemos ser precisos, poderíamos ter obtido os mesmos resultados através do comando seguinte:

MSH c:\>get-wmiobject Win32_logicalMemoryConfiguration -namespace root\cimv2

O parâmetro -list pode ser usado sempre que for necessário obter uma listagem de todas as classes existentes no interior de um namespace. Portanto, se quisermos ver todas as classes mantidas no interior do namespace, podemos recorrer ao seguinte comando:

MSH c:\>get-wmiobject -list

No seguimento dos conceitos apresentados, não será surpresa se afirmar que o comando anterior apresenta as classes existentes no interior do namespace predefinido (ou seja, as classes mantidas no namespace root\cimv2). Se  estivermos interessados em apresentar as classes existentes noutro namespace, então devemos utilizar o parâmetro -list em conjunto com o parâmetro -namespace.

Este cmdlet apresenta ainda outros parâmetros interessantes, como por exemplo, o parâmetro -cedential. Este parâmetro permite-nos definir as credenciais que serão associadas ao comando. Este parâmetro dá imenso jeito já que permite-nos impersonalizar um utilizador para executar a operação pretendida (algo que dá sempre jeito se estiverem a usar uma conta não administrativa – se não o estão a fazer neste momento, então está na hora de começarem  – ou se precisarem de executar o comando sobre outra máquina). O parâmetro pode receber um objecto do MshCredential que é capaz de guardar o par nome de utilizador/palavra-chave que identificam a conta de um utilizador. A construção deste objecto pode ser feita de várias formas.

A forma mais simples de usar este parâmetro consiste em associá-lo apenas so nome de utilizador. Neste caso, temos apenas de fazer o seguinte:

MSH c:\>get-wmiobject Win32_logicalMemoryConfiguration -namespace root\cimv2 -credential Maquina\utilizador

A execução do comando anterior resulta na apresentação de um diálogo que permite a introdução da palavra-chave associada ao utilizador Maquina\utilizador. Apesar de interessante, esta solução não é adequada quando pretendemos executar várias acções num script. Nestas situações, podemos obter as credenciais de um utilizador e mantê-las numa variável que será usada posteriormente:

MSH c:\>$mycredentials = get-credential

MSH c:\>get-wmiobject Win32_logicalMemoryConfiguration -namespace root\cimv2 -credential $mycredentials

No exemplo anterior, as credenciais introduzidas pelo utilizador são mantidas na variável $mycredentials (como era de esperar, o cmdlet get-credential retorna um objecto do tipo MshCredential). A utilização desta estratégia permite reutilizar as credenciais introduzidas nos comandos executados posteriormente. De volta ao cmdlet get-wmiobject, para referir que a indicação da máquina onde o comando é executado é determinada pelo parâmetro -computer. Assim, se desejarmos obter a memória do computador OMEGA, teríamos de recorrer a uma instrução semelhante à seguinte:

MSH c:\>get-wmiobject Win32_logicalMemoryConfiguration -computer OMEGA

Apesar do exemplo não o indicar, é bem provável que a correcta execução deste comando só seja possível através do envio de credenciais. Para terminar a apresentação deste cmdlet, falta apenas apresentar dois parâmetros: -property e -filter. O parâmetro -property recebe um array de strings que indicam as propriedades que devem ser seleccionadas do objecto retornado pelo comando. Por exemplo, vamos supor que estamos apenas interessados em obter a memória virtual existente na máquina. Nesse caso, podemos executar apenas o seguinte comando:

MSH c:\>get-wmiobject win32_logicalmemoryconfiguration -property totalvirtualmemory

TotalVirtualMemory : 3568752
__GENUS            : 2
__CLASS            : Win32_LogicalMemoryConfiguration
__SUPERCLASS       :
__DYNASTY          :
__RELPATH          :
__PROPERTY_COUNT   : 1
__DERIVATION       : {}
__SERVER           :
__NAMESPACE        :
__PATH             :

O exemplo anterior é duplamente interessante: em primeiro lugar, permite-nos demonstrar os passos necessários à obtenção de algumas propriedades associadas ao objecto retornado pelo wmi. Para além disso, permite-nos ainda perceber que, ao contrário do que poderíamos pensar inicialmente, a propriedade totalvirtualmemory também devolve um objecto (prometo que nos posts futuros vou falar acerca das várias opções de formatação disponibilizadas por esta shell). Para terminar, temos ainda de falar acerca do parâmetro filter. Este parâmetro permite-nos definir um filtro capaz de, como o próprio nome indica, filtrar os dados devolvidos pelo cmdlet get-wmiobject.

Bem, parece-me que por hoje já chega  Apenas dois links para aqueles que queiram obter mais informação em relação ao use do WMI:

http://msdn.microsoft.com/library/en-us/dnclinic/html/scripting06112002.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting08132002.asp

 

Now playing: Moonspell - Abysmo

por Luis Abreu | with no comments
Filed under: , ,
OSCON 2005 Keynote: Identity 2.0
13-2-2006 23:07
Mas que grande apresentação!
por Luis Abreu | 6 comment(s)
Filed under: ,
Se colocar o meu tipo num ficheiro no interior da pasta app_code...
11-2-2006 0:07

então não é necessário indicar a assembly onde o tipo foi definido se necessitarmos de adicionar uma linha no web.config para carregar esse tipo, certo? (ex.: utilização do elemento <add> para adicionar um tipo a uma lista de providers)

Bem, a resposta à questão anterior é: talvez. E talvez porquê? Afinal de contas, quando, por exemplo, criamos um novo provider de membership num ficheiro colocado no interior da pasta app_code, a plataforma encarrega-se de carregar esse tipo se adicionarmos uma linha semelhante à seguinte ao web.config:

<add name=”myProvider” type=”namespace.typename” />

Contudo, se tentarmos fazer algo semelhante para a secção <webRequestModules>, vamos deparar-nos com uma excepção que indica que não foi possível encontrar o tipo. Isto acontece por uma razão: a obtenção de tipos usados pelos providers usados pelo ASP.NET é feita (em última análise) pelo método GetType da classe BuildManager (ao contrário do que normalmente acontece, onde os tipos são carregados através do método GetType exposto pela classe Type). A classe BuildManager começa por tentar obter o tipo através da classe Type e, se tal não for possível, encarrega-se de o procurar nas assemblies dinâmicas associadas à aplicação actual (como é óbvio, a assembly gerada a partir dos ficheiros mantidos no interior da pasta app_code encontra-se entre estas assemblies).

Voltando ao exemplo do <webRequestModules>, como fazemos se quisermos adicionar uma entrada no interior de este elemento em que o tipo é mantido no interior da pasta app_code? Bem, neste caso a solução é simples, já que podemos adicionar uma entrada semelhante à seguinte:

<add name=”myProvider” type=”namespace.typename, app_code” />

Por esta altura, os mais curiosos já verificaram a pasta temporária associada à aplicação e interrogam-se sobre como é possível a instrução anterior funcionar já que app_code é apenas parte do nome da assembly que contém os ficheiros mantidos no interior da pasta especial app_code. Bem, para além de tentar carregar os tipos cuja assembly não é indicada, a classe BuildManager encarrega-se ainda de tratar o evento AssemblyResolve gerado pela classe AppDomain. Este evento, que é gerado quando a resolução de uma assembly falha, é usado pela classe para efectuar a tradução de alguns nomes especiais de forma a associá-los às assemblies “reais” usadas pela aplicação (app_Code é apenas um desses nomes; para além desse, existem outros. Por exemplo, quando usamos subpastas no interior da pasta app_code, podemos também usar o termo app_subcode_nomesubpasta).

E esta é a explicação mais sucinta que se pode efectuar acerca do processo de resolução de assemblies usado pela plataforma ASP.NET.

Antes de terminar, queria deixar um agradecimento ao Paulo Morgado pela colaboração no desenvolvimento deste post.

por Luis Abreu | with no comments
Filed under: , ,
Monad - wildcards e expressões regulares
2-2-2006 21:47

Após alguns dias de “folga”, está na hora de cumprir o prometido, isto é, de voltar a falar acerca do Monad. Hoje vou apresentar vários aspectos relacionados com a utilização de wildcards e expressões regulares. Ambos as  opções permitem-nos executar acções contra um conjunto de itens que estão de acordo com as regras definidas através dessas opções. Vamos começar pelos wildcards.

À semelhança do que acontecia com a CMD.EXE, esta nova shell suporta o uso de wildcards. Actualmente, a shell suporta os seguintes wildcards:

  • *: representa uma correspondência a zero ou mais carácteres. Por exemplo, se usarmos a expressão *, então aceitamos qualquer elemento; por outro lado, a expressão l* retorna apenas itens começados por l.
  • ?: representa uma emcorrespondência de apenas um carácter. Por exemplo, a expressão abr? retorna elementos designados de abri, abre, etc.
  • []: pode ser usado para representar intervalos ou conjuntos de caracteres. A expressão [a-d]ri retornará todos os elementos começados por um carácteres existentes no intervalo a-d seguidos do texto ri; por outro lado, [ad]ri só retornará os elementos com nome ari ou dri, já que neste caso, [] apresenta apenas uma lista de caracteres  vez de um intervalo.

Muitos dos cmdlets usados permitem o uso de  wildcards de forma a permitir a filtragem de itens retornados. O exemplo clássico consiste na obtenção de determinados ficheiros existentes no interior de uma pasta:

MSH c:\>get-childitem c:\teste\*.doc

Neste exemplo, a shell irá apresentar todos os ficheiros de word existentes no interior da pasta teste. É importante salientar que os caracteres anteriores podem ser combinados de forma a obtermos uma expressão complexa que permite restringir ainda mais os elementos retornados pelo cmdlet.

Apesar de permitirem a execução de alguns comandos interessantes, a utilização de wildcards não possui o mesmo poder associado às expressões regulares. Ao contrário do que acontecia com os wildcards, as expressões regulares permitem-nos construir expressões constituídas por regras complexas. Felizmente para nós, as expressões regulares permitem-nos explicitar praticamente todos os padrões que desejamos. Infelizmente para o blog, não é possível apresentar aqui todas as características relacionadas com este tipo de expressões (por outro lado, existem vários sites na internet que contém dados relacionados com este tipo de elementos).

Convém referir que o Monad possui alguns operadores que normalmente são usados com os wildcards e expressões regulares: (c)like/notlike e (c)match/ notmatch. O primeiro par é usado normalmente com wildcards; por sua vez, o segunto é usado na avaliação de expressões regulares. O exemplo seguinte ilustra a utilização do operador -match em conjunto com uma expressão regular:

MSH c:\>get-childitem | where-obejct{ $_.Name -match “con\d” }

Este exemplo devolve todos os elementos cujo nome começa por con e termina com um algarismo. Nos próximos posts vamos continuar a falar acerca das funcionalidades do Monad e vamos introduzir o cmdlet get-wmiobject que, como o próprio nome indica, permite efectuar a gestão do sistema operativo através de objectos WMI.

por Luis Abreu | with no comments
Filed under: , ,
Multiview e Wizard
1-2-2006 23:09

Hoje produzi mais um pequeno vídeo sobre a utilização destes dois novos controlos. Na verdade, não sei se este ficou melhor do que o primeiro, mas penso que transmite os principais aspectos relacionados estes dois controlos simples. Para a próxima, vou ter mesmo de fazer um guião para não me perder durante a apresentação (e, já agora, comprar um micro novo porque este deixa muito a desejar…). Como sempre, criticas e sugestões são bem-vindas!

Nos próximos posts, vou regressar ao Monad

[Update: Parece que  acabei colocando apenas o ficheiro wav com o som. Portanto, os interessados vão ter de esperar mais umas horas pelo produto final já que o ficheiro wmv está em casa e eu estou a trabalhar :(]

[UPDATE: Bem, espero que desta seja de vez. Já actualizei o link com o vídeo.]

por Luis Abreu | 3 comment(s)
Filed under: , ,