Adicionar novas línguas ao Windows (edições Home)

July 2nd, 2010

Eu desenvolvo sobre Windows, sobre um Windows 7 Home Premium, para ser mais exacto. E ao longo do tempo tenho sofrido de alguns obstáculos oferecido pelas limitações da versão. A versão é a que veio com o PC, e pretendo puxá-lo até onde possível, antes de fazer um upgrade para um Business ou Ultimate (apesar das restantes máquinas – desktop – aqui do escritório estarem com o Ultimate).

Mas infelizmente ontem, deparei-me com um problema que demorou a tarde toda a perceber, e quando assim é, é geralmente algo do OS e nada óbvio. Contextualizando, estou numa fase de internacionalizar uma aplicação web de gestão de currículos e processos de recrutamento e selecção, que desenvolvi no ano passado (e ainda este ano). Foi grande sucesso junto da equipa de trabalho, pois permitiu acelerar em muito os processos de recrutamento, que dado o volume de candidaturas que lhes chegavam – dezenas de milhares em meio ano – era tediante e constrangedor. Felizmente, a app foi criada à medida da equipa e adaptado ao processo de trabalho, e resultou em pleno.

De qualquer forma, a app está a ser internacionalizado para suportar as acções em Espanha, e o processo de internacionalização tem os seus próprios desafios associados – a globalização da aplicação para não ter dependências directas da língua nem numeração, e a localização para corresponder a cada realidade, quer de linguagem, quer de informação (por exemplo as diferenças de moradas e códigos postais e informação regional).

Sei que esta fase trará alguns problemas de estrutura e configuração – umas mais complicadas que outras – e a primeira apareceu logo na base de dados. Para a aplicação, optei pelo suporte de dados em base de dados relacional, e a base escolhida foi o PostgreSQL. Tem óptimas capacidades de armazenamento, suporte a pesquisa em XML, indexação e pesquisa de texto livre com o tSearch2, e é OpenSource que também foi muito atractivo na escolha.

Quando se cria uma base de dados no Postgre, o único parâmetro obrigatório é o nome da base de dados. As restantes definições são preenchidas com os valores pré-definidos da instalação. As que condicionam a base e que só podem ser definidas na criação são o LC_COLLATE e o LC_CTYPE. A primeira – LC_COLLATE, determina a forma como são ordenadas as palavras e que pode variar de cultura para cultura. O mesmo para o LC_CTYPE que caracteriza os caracteres em termos de maiúsculas, minúsculas, e pontuação

O problema destes parâmetros são a dependência do OS para esta informação. Seria muito interessante se dependesse apenas da base de dados e os executáveis associados, mas na verdade esta informação vem do sistema operativo. Por defeito, o valor para as variáveis são o da definições do OS. O Windows Server 2008 permite que o utilizador possa configurar a sua conta para definições regionais e linguísticas diferentes e que podem ser acrescentados através de MUIs (Multilingual User Interface). O mesmo é possível nas versões do Business e Ultimate do Windows. Infelizmente, no Home Premium não é possível, sem alguns workarounds.

Como afecta a criação da base? Simples. Se não tiver as definições linguísticas instaladas na máquina, não posso criar a base de dados usando essas definições, apenas com as existentes. Para portuguese, e portanto com base na definição do OS, tenho quer para LC_CTYPE, quer para LC_COLLATE o valor:

Portuguese_Portugal.1252

Para a base espanhola queria

spanish_Spain.1252

Acrescentar definição no Windows Server 2008

Trabalhamos aqui geralmente com duas instâncias de base de dados, uma local e uma remota, centralizada. Procurei resolver primeiro o caso no server, para verificar se era mesmo este o problema. Não tinha o pack espanhol instalado, e portanto puxei-o do site da Microsoft:

http://www.microsoft.com/Downloads/details.aspx?familyid=03831393-EEF7-48A5-A69F-0CE72B883DF2&displaylang=en

ou para o Server 2008 c/ SP2

http://www.microsoft.com/Downloads/details.aspx?familyid=3A7FB7A2-3519-495B-9BC5-2007082CA9A6&displaylang=en

ou para Server 2008 R2

http://www.microsoft.com/Downloads/details.aspx?familyid=03831393-EEF7-48A5-A69F-0CE72B883DF2&displaylang=en

são ficheiros .img pelo que devem ser carregados numa drive virtual como o Virtual Clone Drive.

Depois em Control Panel > Regional and Language Options > Keyboards and Languages > Display Language aparece a lista de linguagens disponíveis e em uso pelo Windows. Há tb um botão “Install/uninstall Languages” que permite acrescentar. Deve no Wizard que aparece escolher a pasta da drive para a linguagem especifica e deixar correr a instalação.

No caso do espanhol, puxei o ficheiro do grupo 1, e no wizard escolhi a pasta “es-ES”. “Et voilá”, spanish_Spain.1252 fica disponível no PostgreSQL. Simples e resolvido.

O processo para as versões do 7 Ultimate e Business devem ser semelhantes. O problema surge para o Home. Não é suportado, mas é possível introduzir as definições de localização. Para tal guiei-me pelas notas em http://xaueious.wordpress.com/2009/08/22/changing-installed-language-of-windows-7-home-premium-pro-from-en-us/ e segui o caminho da linha de comandos.

Acrescentar definição no Windows 7 Home Premium

  1. Descarregue o MUI associado à língua específica daqui http://www.froggie.sk/7lp64rtm.html
  2. Agora um dos truques: Se executares o ficheiro descarregado, é extraído um ficheiro “lp.cab” para a mesma pasta e que é fundamental preservar. No entanto, pouco depois de executar, o ficheiro desaparece. Portanto considera-o um pouco como um jogo de reacção, e prepara o ambiente para mover o ficheiro para outro local ou renomea-lo ASAP. Copy-paste não resulta.
  3. Na linha de comandos, executado com privilégios de administrador, executa o seguinte comando:
    DISM /Online /Add-Package /PackagePath:D:\Caminho\lp.cab

    onde D:\Caminho\lp.cab é o caminho completo para o ficheiro extraído.

  4. O processo demora uns minutos, mas uma vez findado, no Postgre, é possível criar a base com as chaves de locale correctas e desejadas.

O tab do ASP.NET desapareceu no IIS!!??

August 21st, 2009

Não aconteceu comigo, mas ontem foi, talvez, a segunda vez que ouvi falar desta situação. um colega ontem teve o mesmo problema e ajudei a encontrar uma solução para o problema. Aparentemente, até é um problema comum e parece estar relacionado com um parâmetro de configuração de módulos 32bits em 64bits, e especialmente de Windows Server 2003 instalado num VMWare Server. A solução está descrita em vários locais da web – vou apenas transcrever/traduzir a solução para que possa ser útil a mais pessoal.

  1. Pare o serviço do IIS
  2. Localize o ficheiro “metabase.xml” em c:\windows\system32\inetsrv e abra-o no notepad ou outro editor
  3. Procure a linha que tenha a chave “Enable32BitAppOnWin64″ e elimine-o
  4. Guarde o ficheiro
  5. Reinicie o IIS (e restantes serviços que possam ter parado)
  6. Verifique que a tab existe

Esta solução está em http://www.bobnedved.com/post/2007/12/My-ASPNET-Tab-is-missing-in-IIS!!.aspx

Limitações do IIS 7 no Windows Vista

September 17th, 2008

É pelo menos a segunda vez que tenho que enfrentar problemas de limitações do sistema operativo, e é nesta altura que mais detesto a Microsoft e o seu sistema operativo. Mas enfim, são as regras do jogo que nos impõe. E é nesta altura que gostava que o mundo fosse o Ubuntu.. hehehe

Desta vez, no desenvolvimento de uma aplicação que faz grande uso de serviços, e até encadeamento de acessos. Em termos de produção, trata-se de um sistema distribuído, mas todo o desenvolvimento é efectuado numa só máquina, com os diversos serviços integrados em directorias virtuais com se fossem servidores distintos. Uma abstracção que permite-me ter alguma flexibilidade no desenvolvimento da(s) aplicação(ões).

Esta abordagem tem, no entanto, problemas associadas. Cada chamada a um serviço é uma chamada na contagem, e porque o processo exige pedidos síncronos, o anterior tem que aguardar pela resposta do seguinte. Após horas a batalhar com a questão e após um esforço grande de logging, encontrei o local do problema – uma operação que teoricamente é simples e rápida, mas que exigia um pedido a um serviço. O tempo de execução entre a chamada anterior e a seguinte era sempre de 1m30s. Só depois deste periodo (em que a aplicação dava um timeout, nas camadas superiores) é que os pedidos em espera eram executados (quase instantaneamente).

O giro disto tudo, e o que me levou a desconfiar do IIS / Vista foi o facto de este problema surgir apenas com o acesso à aplicação via IIS. Usando o servidor de desenvolvimento do Visual Studio, o pedido passava sempre, sem problemas. Detectado o ponto de falha, e com este conhecimento da potencial falha, um pouco de pesquisa no Google apresenta a causa. IIS 7 em Vista Home Premium.

O Home Premium admite sevrir páginas e desenvolvimento para aplicações simples, sem dúvida. E até agora só encontrei dois problemas com ele em termos de desenvolvimento. Mas para algumas aplicações mais complexa como o caso da minha torna-se problemático e é muito díficil encontrar o bicho que causa o problema.

Em Stuff that Just Works, de Cal Zant há uma página que apresenta o conjunto de limitações que as versões do Windows apresentam. Com o XP Pro, e IIS 6, a limitação era de 1 site e 10 ligações concorrentes. O XP, versões básicas, não permitiam o IIS. Com o vista, mais ou menos a mesma situação surge – para as versões Business e superiores, o numero de ligações concorrentes são ilimitadas, mas passou a haver limite no numero de pedidos simultâneos, e a restrição do número de sites desapareceu.

Já com o Home Basic Premium, que é o unico dos Home a suportar o IIS, a intenção é suportar as necessidades de desenvolvimento casual e portanto entram as limitações – processamento de três pedidos em simultâneo e sem o suporte a configurações de segurança avançadas – exactamente os dois pontos problemáticos para mim…

Em termos de mudança relativo ao IIS 6 no XP Pro, enquanto neste era possível que apenas 10 utilizares dessem inicio a sessão (mas podendo fazer quantos pedidos quisesse), com o IIS 7 em Vista, podem estar ligados quantos quiserem, mas apenas 10 (ou 3) pedidos estarão a ser processados em qualquer momento e as restantes permanecem em fila de espera o que permite que os utilizadores se mantenham ligados à aplicação, mas eventualmente com demora na resposta. No meu caso, como os 3 em execução estavam dependentes de um 4 que estava em espera, apenas o timeout do primeiro permitiu a continuação da execução.

Acredito que sejam limitações impostas pela Microsoft para de alguma forma puxar as empresas a comprarem as versões de servidor (em termos de ambiente de utilização) e para o programador mover-se para um SO “mais completo”. Mas que são situações chatas (e caras), lá isso são!!!

Em IIS.Net, há ainda a lista completa das diferenças do IIS entre versões do Vista…

IPNat.sys & a Firewall no Windows 2003

August 13th, 2008

Um problema de hoje – estava a tentar reconfigurar o BackupPC para efectuar backups de clientes Windows. Neste caso, decidi experimentar o rsyncd em vez do Samba. No entanto enquanto tentava abrir a FireWall do windows, para abrir uma excepção, surgia a seguinte mensagem:

O Firewall do Windows não pode ser executado pois está sendo executado outro programa ou serviço que pode usar o componente de conversão de endereço de rede (Ipnat.sys)</pre>

Fartei-me de ligar e desligar serviços e mesmo parar o Ipnat via o commando 

<pre>sc stop ipnat

sem sucesso. Finalmente encontrei este post num forum que resolveu. Bastou desligar o “Encaminhamento e Acesso Remoto” em Meu Computador -> Gerir -> Serviços e Aplicações para voltar a ter acesso à Firewall.

Utilizar o AzMan no XP

August 9th, 2008

O Authorization Manager (ou AzMan) é uma implementação de uma architectura baseado em perfis (RBAC – Role Based Access Control). Com o Azman, podemos definir um conjunto de perfis para uma aplicação, definir os utilizadores que herdam cada perfil, e depois na aplicação gerir os acessos a operações (e não apenas à aplicação em si) pelos perfis.

Os utilizadores que associamos pode vir de variadíssimas fontes como um ficheiro XML, uma AD ou ainda num ADAM. O caso da AD é óptimo para implementar métodos de single sign-on, especialmente em aplicações que correm numa intranet, permitindo conceder autorização a operações em aplicações por utilizadores já autenticados no domínio. E integra-se com relativa facilidade no DotNet, utilizando as classes de Membership e Roles existentes.

O AzMan é parte integral do Windows 2003, mas é possível utiliza-lo no 2000 ou XP. Aliás surgiu uma aplicação em que tive de o implementar numa web app a correr num “servidor” baseado numa máquina com o XP. Infelizmente a instalação no XP não é imediato. É necessário introduzir dois elementos, principalmente – o Snap-in de administração (para ter um UI de administração dos acessos e criar o armazem de associações) e as classes próprias para o .NET.

O processo:

  1. Instale o Windows Server 2003 Administration Tools Pack. Este passo instala uma serie de ferramnetas e snap-ins típicos do Server 2003, incluindo o AzMan que nos interessa.

  2. A instalação inclui o snap-in (azman.msc) mas não inclui a dll (primary interop assembly). Para isso deve instalar o Windows 2000 Authorization Manager Runtime. Depois de extrair, é necessário registar o Microsoft.Interop.Security.AzRoles.dll no GAC do .NET. Abre a ferramenta de configuração do .NET (Painel de controlo -> Ferramentas administrativas -> Microsoft .Net 2.0 Configuration Tool; Caso não esteja disponivel pode ser necessário instalar o SDK). Na ferramenta de configuração, segue para o Assemblies Cache e adiciona a dll presente em Windows(R) 2000 Authorization Manager Runtime\PIA\1.2.

Deste modo, o servidor da aplicação, em XP, fica preparado para utilizar o AzMan (Felizmente no server 2003 é bem mais facil…). Resta agora criar as políticas e configurar a aplicação. Para configurar as políticas:

  1. Excute o azman.msc, para abrir o snap-in e criar as políticas e crie uma nova authorization store. Eu, por exemplo, e para o que necessitava, armazenei as poíticas num ficheiro XML, numa pasta não acessivel por web. A criação das politicas deve ser efectuado em modo developer (Action -> Options -> Developer Mode).

  2. Crie uma nova aplicação.
  3. Em Definitions -> Role Definitions adiciona os nomes dos perfis que necessitas. No meu caso, só queria incluir uma forma simplificada de autenticação e portanto apenas criei um grupo chamado AppUsers. O AzMan permite incluir também operações se necessitares.
  4. Em Role Assignments adiciona o(s) perfil(s) adicionado(s) e a cada perfil adiciona os utilizadores (da máquina e/ou AD) ao perfil. O Windows, durante o processo de autenticação ira atribuir o perfil ao utilizador.
  5. Atribui permissões ao utilizador ASPNET (ou equivalente) para aceder ao ficheiro XML criado, no caso de estar a usar um ficheiro XML.

Para configurar a aplicação para utilizar o AzMan,

  1. Adiciona a connection string, no caso de usar o ficheiro XML, à lista de connection strings:

     
    <configuration> 
      <connectionstrings> 
        <add name="LocalPolicyStore">
             connectionString="msxml://c:/Aplicação/azman.xml" />;
      </add> 
    </connectionstrings>
     
    </configuration>
  2. Define no o RoleProvider:
    <system.web>
        <roleManager 
            enabled="true" 
            cacheRolesInCookie="true" 
            defaultProvider="RoleManagerAzManProvider"
            cookieName=".ASPXROLES" 
            cookiePath="/" 
            cookieTimeout="30" 
            cookieRequireSSL="true" 
            cookieSlidingExpiration="true"
            createPersistentCookie="false" 
            cookieProtection="All">
            <providers>
               <add name="RoleManagerAzManProvider"
                    type="System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=2.0.0.0, 
                        Culture=neutral, publicKeyToken=b03f5f7f11d50a3a"
                    connectionStringName="LocalPolicyStore" 
                    applicationName="Nome da Aplicação"/>
            </providers>
        </roleManager>
    </system.web>

    onde applicationName é o nome da aplicação atribuída no AzMan

  3. A partir daí posso defenir no web.config as regras de autoriação para uma pasta, com base no perfil:

     
    <authorization>
       <allow roles="AppUsers" />
       <deny users="*" />
    </authorization>

    ou utilizar a API do Azman para definir e testar autorizações (até ao nível da operação).

Mais informação em http://msdn.microsoft.com/en-us/library/ms998336.aspx