Lançamento do SDK do Windows Embedded 8 Handheld

A primeira década deste século viu chegar os primeiros smartphones, tendo o nº de escolhas para os consumidores e empresas aumentado progressivamente, até à omnipresença que hoje conhecemos.


A Microsoft foi das primeiras empresas a disponibilizar equipamentos desse tipo, com ou sem ecrã tátil, uns mais orientado a consumidores e outros a empresas, o que lhe permitiu gozar de algum sucesso em alguns mercados, até ao lançamento dos primeiros iPhone.


Se a oferta da Microsoft para o mercado de consumo rapidamente definhou, sendo o Windows Phone 6.5 lançado em 2010 a última versão do sistema operativo, no mercado profissional dos terminais robustos continuam a ser lançados novos modelos naquele que é agora conhecido como Windows Embedded Handheld 6.5, WEH 6.5 daqui em diante. O WEH 6.5 parte do Windows Phone 6.5.3, e continua a ser uma excelente plataforma para aplicações Line of Business, contando com um ambiente e experiência de desenvolvimento que não obstante ter mais de 5 anos (continua  a ser requerido o Visual Studio 2008 para desenvolver para a .NET Compact Framework 3.5), apresenta ainda muitas vantagens sobre plataformas móveis mais recentes. A título de exemplo, o WEH 6.5 é a única plataforma móvel que conta com verdadeiros motores de base de dados, como SQL Server Compact, IBM DB2, Oracle Lite, Sybase ASA e Ultralite, todos com poderosas tecnologias de sincronização e capacidade para gerir de forma performante volumes de dados que podem atingir milhões de registos traduzidos em bases de dados com centenas de MB  que, inexplicavelmente, não encontram paralelo nas plataformas móveis atuais. Outro exemplo, a que os decisores raramente prestam a atenção devida, enquanto qualquer das plataformas móveis reinantes atualmente, incluindo as da Microsoft, tem um ciclo de vida e suporte que quando existente não passa dos 24 meses, o WEH 6.5 tem garantia de suporte por parte da Microsoft até… 2020!


Apesar de ainda ter alguns argumentos, o WEH 6.5 também apresenta limitações sérias, sendo a principal para muitos a obsolescência da sua plataforma de desenvolvimento, que não conhece nenhum dos desenvolvimentos do .NET posterior à sua versão 3.5 (async, PCL, UI modernas, padrão MVVM, …) e obriga a manter o Visual Studio 2008 instalado.


Aquando do anúncio do Windows Phone 7 em 2010, aventou-se a possibilidade de surgir uma nova versão do Windows Embedded Handheld baseada na nova plataforma de consumo, o que nunca se concretizou, e que foi sendo adiado até ao anúncio no início deste ano do Windows Embedded 8 Handheld (WE8H) num evento em Nova Iorque, onde fabricantes como a Motorola, a Intermec, a coreana Bluebird e a Ingenico - conhecida pelos seus terminais de pagamento, alguns baseados em Windows CE – se juntaram a esse anúncio da Microsoft. O WE8H é uma plataforma para equipamentos profissionais baseada em Windows Phone 8, com tudo o que isso traz de positivo, nomeadamente em termos da experiência de desenvolvimento que parte das ferramentas associadas ao Windows Phone 8, que acrescenta funcionalidades requeridas pelas empresas, como o lock down dos equipamentos às aplicações permitidas e a gestão centralizada de equipamentos por ferramentas da Microsoft ou de terceiros, a leitura ótica de códigos de barras com leitores dedicados, e baterias e robustez superiores aos dos equipamentos de consumo. O SDK do WE8H expõe de forma standard o acesso às funcionaidades expostas pelo mesmo, o que significa que podemos fazer uma aplicação que dependa da leitura ótica e que corre em qualquer equipamento WE8H independentemente do seu fabricante, o que não acontecia até aqui.


Enquanto se aguarda o lançamento de equipamentos baseados no novo sistema operativo no 2º trimestre de 2014, a Microsoft acaba de libertar alguns recursos que permitem desde já tomar contato com o WE8H:


  • Anúncio da disponibilização do WE8H aos fabricantes
  • SDK que expõe as funcionalidades extra em relação ao SDK do Windows Phone 8
  • Emulador que permite simular a leitura ótica, além dos simuladores do Windows Phone 8
  • Página na MSDN dedicada ao WE8H

Antecipando aquela que pode ser a primeira questão que quem já desenvolveu para a .NET Compact Framework pode ter, não há nenhuma caminho de migração de aplicações desenvolvidas para .NET CF para o modelo de desenvolvimento do Windows Phone 8/WE8H, embora dependendo da forma como as aplicações estejam estruturadas se possa reutilizar e/ou partilhar código entre elas. A ter em conta que o modelo de UI é completamente diferente e que não há motores de base dados “a sério” para a nova plataforma, embora existam diferentes propostas “no sql” para armazenamento local, como o SiaQoDb, SQlLite, Lex.DB, entre outras.

Passar um objeto List<string> para uma SP SQL Server, usando XML e LINQ

Surgiu-me a necessidade de passar uma lista de valores variável para uma Stored Procedure de SQL Server. A opção que me pareceu mais adequada foi tirar partido do suporte a XML presente no SQL Server desde a versão 2000.


Primeiro que tudo é necessário passar o objeto List genérico para XML (C#):


List<string> l = new List<string>() { “a”, “b”, “c”, “d”, “e” };
XDocument xmlDocument =
new XDocument(
         
new XDeclaration(“1.0″, “UTF-8″, “yes”),
         
new XElement(
                
“Locations”,
                 l.Select(n =>
new XElement(
                         
“Location”
                          
new XAttribute(“id”, n)))));
string s = xmlDocument.ToString(SaveOptions.DisableFormatting);


 Dado que o XML produzido não se destina a ser humanamente lido, a flag “DisableFormatting” previne que seja adicionadas desnecessárias quebras de linha e indentação. Neste caso escolhi gerar um XL com atributos:


 

Do lado do SQL Server, podemos facilmente gerar uma tabela a partir do XML recebido, que poderemos utilizar como necessário (T-SQL):

DECLARE @x AS XML
SET @x=’<?xml version=”1.0″ encoding=”utf-8″?><Locations><Location id=”a”/><Location id=”b”/><Location id=”c”/><Location id=”d”/><Location id=”e”/></Locations>’

DECLARE @i int
EXEC sp_xml_preparedocument @i OUTPUT, @x;

SELECT location
FROM OPENXML(@i, ‘/Locations/Location’, 1)
WITH (location nvarchar(50) ‘@id’ )

EXEC sp_xml_removedocument @i

[2013-12-15] Removi a formatação no código T-SQL e corrigi o código apresentado


<?xml version=”1.0″ encoding=”utf-8″?><Locations><Location id=”a”/><Location id=”b”/><Location id=”c”/><Location id=”d”/><Location id=”e”/></Locations>

Actualização de post sobre "Comunicação de documentos de transporte à AT a partir da .NET Compact Framework "

Actualizei o meu post anterior sobre “Comunicação de documentos de transporte à AT a partir da .NET Compact Framework ” pois aquando da sua publicação não me apercebi que para funcionar era necessário instalar previamente os certificados na Certificate Store do PDA, que era precisamente o que eu queria evitar. A nova versão do código e o novo componente utilizado permitem concluír com sucesso o processo de comunicação de documentos de transporte à AT:


http://msmvps.com/blogs/albertosilva/archive/2013/04/09/comunica-231-227-o-de-documentos-de-transporte-224-at-a-partir-da-net-compact-framework.aspx

Comunicação de documentos de transporte à AT a partir da .NET Compact Framework [reactualizado a 2013/06/17]

(post revisto a 2013/06/17, alterado código exemplo e link para componente)


A partir de 1 de Maio, os documentos de transporte terão de ser comunicados previamente à AT, sendo uma das formas disponibilizadas e aquela que se afigura mais prática, a comunicação via webservices, que permite na resposta obter o código atribuío pela AT ao documento transmitido.


Com base na informação num tópico no Portugal-a-programar, comecei a semana passada um projecto de testes para validar se a comunicação em causa poderia ser feita directamente a partir da .NET Compact Framework, o que se afigurava difícil dadas as limitações da .NET CF a lidar com certificados, nomeadamente o carregamento de .pfx e a utilização de .cer para encriptar a informação. Depois de dias a investigar Platform Invokes para o efeito sem sucesso, e de ter confirmado que uma ou outra solução candidata não produzia resultados válidos quando comunicados aos serviços da AT, acabei por fazer aquilo que deveria ter feito em 1º lugar: procurar um componente de terceiros que fizesse o serviço, e assim no www.componentsource.com descobri um componente que, não sendo caro, resolve as duas limitações que tinha encontrado.


O seguinte método em C# devolve o resultado da chamada ao serviço:


public static string testa()
{
    string endpoint = “https://servicos.portaldasfinancas.gov.pt:401/sgdtws/documentosTransporte”;
    string senhaCertificado = “xxxxxxxxxx”;

    string userPortal = “xxxxxxxxx/x”;
    string passwordPortal = “xxxxxxx”;


    string horaCriacaoCifrada;
    string senhaCifrada;
    string nonce;

    SBUtils.Unit.SetLicenseKey(colocar aqui a chave incluída no ficheiro C:\Program Files (x86)\EldoS\SecureBlackbox.NET\Assemblies\NET_CF20\LicenceKey.txt);

    String DataCriacao = DateTime.Now.ToUniversalTime().ToString(“yyyy-MM-ddTHH:mm:ss.ff”) + “Z”;

   
RijndaelManaged rijndaelCipher = new RijndaelManaged();
    rijndaelCipher.GenerateKey();
    rijndaelCipher.Mode = CipherMode.ECB;
    rijndaelCipher.Padding = PaddingMode.PKCS7;
    SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
    rijn.Key = rijndaelCipher.IV;
    rijn.IV = rijndaelCipher.IV;
    rijn.Mode = CipherMode.ECB;
    MemoryStream msPassFinancas = new MemoryStream();
    CryptoStream csPassFinancas = new CryptoStream(msPassFinancas, rijn.CreateEncryptor(rijn.Key, rijn.IV), CryptoStreamMode.Write);
    using (StreamWriter swPassFinancas = new StreamWriter(csPassFinancas))
    {
        swPassFinancas.Write(passwordPortal);
    }
    MemoryStream msDataCriacao = new MemoryStream();
    CryptoStream csDataCriacao = new CryptoStream(msDataCriacao, rijn.CreateEncryptor(rijn.Key, rijn.IV), CryptoStreamMode.Write);
    using (StreamWriter swDataCriacao = new StreamWriter(csDataCriacao))
    {
        swDataCriacao.Write(DataCriacao);
    }
    senhaCifrada = Convert.ToBase64String(msPassFinancas.ToArray());
    horaCriacaoCifrada = Convert.ToBase64String(msDataCriacao.ToArray());
    RSACryptoServiceProvider AlgRSA = new RSACryptoServiceProvider();

    byte[] rsaModulus = null;
    byte[] rsaPublicKey = null;
    using (TElX509Certificate x509tt = new TElX509Certificate(null))
    {
        //carregar certificado a parir de array de bytes previamente preenchido
        x509tt.LoadFromBufferAuto(_publicCertificate, 0, _publicCertificate.Length,“”);
        int rsaModulusSize = 0;
        int rsaPublicKeySize = 0;
        x509tt.GetRSAParams(ref rsaModulus, ref rsaModulusSize, ref rsaPublicKey, ref rsaPublicKeySize);
        rsaModulus = new byte[rsaModulusSize];
        rsaPublicKey = new byte[rsaPublicKeySize];
        x509tt.GetRSAParams(ref rsaModulus, ref rsaModulusSize, ref rsaPublicKey, ref rsaPublicKeySize);
    }

    RSAParameters rsaP = new RSAParameters()
    {
        Modulus = rsaModulus,
        Exponent = rsaPublicKey
    };
    AlgRSA.ImportParameters(rsaP);
    Byte[] Chave = AlgRSA.Encrypt(rijn.Key, false);
    nonce = Convert.ToBase64String(Chave);

    StringBuilder sb = new StringBuilder();
    sb.Append(“<?xml version=\”1.0\” encoding=\”UTF-8\”?>”);
    sb.Append(“<S:Envelope xmlns:wss=\”http://schemas.xmlsoap.org/ws/2002/12/secext\” xmlns:ns2=\”https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/\” xmlns:S=\”http://schemas.xmlsoap.org/soap/envelope/\”>”);
    sb.Append(“<S:Header>”);
    sb.Append(“<wss:Security>”);
    sb.Append(“<wss:UsernameToken>”);
    sb.AppendFormat(“<wss:Username>{0}</wss:Username>”, userPortal);
    sb.AppendFormat(“<wss:Password>{0}</wss:Password>”, senhaCifrada);
    sb.AppendFormat(“<wss:Nonce>{0}</wss:Nonce>”, nonce);
    sb.AppendFormat(“<wss:Created>{0}</wss:Created>”, horaCriacaoCifrada);
    sb.Append(“</wss:UsernameToken>”);
    sb.Append(“</wss:Security>”);
    sb.Append(“</S:Header>”);
    sb.Append(“<S:Body>”);
   
sb.Append(“<ns2:envioDocumentoTransporteRequestElem>”);
    sb.Append(
    @”<TaxRegistrationNumber>xxxxxxxxx</TaxRegistrationNumber>
      <CompanyName>Empresa para teste Lda.</CompanyName>
      <CompanyAddress>
        <Addressdetail>Centro de Empresas de Taveiro</Addressdetail>
       
<City>Taveiro</City>
        <PostalCode>3045-123</PostalCode>
        <Country>PT</Country>
      </CompanyAddress>
      <DocumentNumber>GT AB/1</DocumentNumber>
      <MovementStatus>N</MovementStatus>
      <MovementDate>2013-05-30</MovementDate>
      <MovementType>GT</MovementType>
        <CustomerTaxID>999999990</CustomerTaxID>
    <CustomerAddress>
        <Addressdetail>Urb. Atras Sol Posto</Addressdetail>
        <City>Faro</City>
        <PostalCode>6000-123</PostalCode>
        <Country>PT</Country>
      </CustomerAddress>
      <CustomerName>Empresa Cliente, LDa.</CustomerName>
      <AddressTo>
        <Addressdetail>Urb. Atras Sol Posto</Addressdetail>
        <City>Faro</City>
        <PostalCode>6000-123</PostalCode>
        <Country>PT</Country>
      </AddressTo>
      <AddressFrom>
        <Addressdetail>Centro de Empresas de Taveiro</Addressdetail>
        <City>Taveiro</City>
        <PostalCode>3045-123</PostalCode>
        <Country>PT</Country>
      </AddressFrom>
      <MovementEndTime>2013-05-30T23:04:36.8111658+01:00</MovementEndTime>
      <MovementStartTime>2013-05-30T22:04:36.8101653+01:00</MovementStartTime>
      <VehicleID>00-AA-11</VehicleID>
      <Line>
        <ProductDescription>Ovos</ProductDescription>
        <Quantity>12</Quantity>
        <UnitOfMeasure>UN</UnitOfMeasure>
        <UnitPrice>0.25</UnitPrice>
      </Line>”
);
    sb.Append(“</ns2:envioDocumentoTransporteRequestElem>”);
    sb.Append(“</S:Body>”);
    sb.Append(“</S:Envelope>”);

    TElX509Certificate x509t = new TElX509Certificate(null);
    // carregar o certificado a partir de um array de bytes previamente preenchido
    x509t.LoadFromBufferPFX(_privateCertificate,senhaCertificado);

    TElHTTPSClient cli = new TElHTTPSClient();
    cli.OnCertificateValidate += new SBSSLCommon.TSBCertificateValidateEvent(cli_OnCertificateValidate);
    cli.RequestParameters.CustomHeaders.Add(“SOAPAction=https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/”);
    cli.RequestParameters.ContentType = “text/xml; charset=utf-8″;
    cli.RequestParameters.Accept = “text/xml”;

    TElMemoryCertStorage mc = new TElMemoryCertStorage();
    mc.Add(x509t, true); // client certificate
    cli.ClientCertStorage = mc;

    MemoryStream response = new MemoryStream();
    cli.OutputStream = response;

    byte[] byteArray = Encoding.UTF8.GetBytes(sb.ToString());

    cli.Post(endpoint, byteArray);
    response.Position = 0;

    StreamReader reader = new StreamReader(response);
    string responseFromServer = reader.ReadToEnd();
    reader.Close();
    return responseFromServer;
}

static void cli_OnCertificateValidate(object Sender, TElX509Certificate X509Certificate, ref bool Validate)

{

    Validate = true;

}


Com esta abordagem não necessário instalar os certificados na Certificate Store dos dispositivos.

Para compilar, será necessário adicionar uma referência às assemblies SecureBlackBox, SecureBlackBox.HTTP, SecureBlackBox.HTTPCommon, SecureBlackBox.SSL e SecureBlackBox.SSLCommon, instaladas na pasta C:\Program Files (x86)\EldoS\SecureBlackbox.NET\Assemblies\NET_CF20\ e mudar o valor da chave passada na chamada ao método SetLicenseKey. Ter em atenção as chaves no XML que reportam a datas, pois a hora início tem de ser posterior à hora actual, a hora fim quando fornecida tem de ser superior à hora início e suponho que a data do documento tenha que ser igual ou anterior à actual.

Hora de balanços

As últimas semanas do ano tem-se revelado ano após ano excelentes alturas para… não marcar nada! Há mil-e-uma coisas que nos comprometemos a fazer “ainda este ano”, a par das outras que somos obrigados a fazer, que acabam por não deixar tempo nenhum livre nessa altura.


Este foi um ano em que o volume de trabalho da moving2u se manteve a um nível elevado, seja em termos de projectos à medida, (em que se evoluiu a aplicação que desenvolvemos para Windows Embedded Handheld (aka Windows Mobile) a MRW utilizada a nível ibérico por mais de 2000 utilizadores que dela dependem para fazer as entregas e brevemente as recolhas, em que desenvolvemos a aplicação de picking para o maior grupo de hipermercados em Portugal, depois de já termos feito outra aplicação no mesmo âmbito para outro grupo de hipermercados), seja de desenvolvimento de produto, em que a nossa nova solução para logística (picking, invnetário, recepção de fornecedores, transferências, encomendas internas, …) foi implementada em alguns cenários muito específicos e que contamos disponibilizar em maior escala durante 2013 para os principais ERP, para além da manutenção da nossa solução para forças de venda, igualmente comercializada pela Primavera com marca própria, e das alterações necessárias à conformidade com a nova legislação para aplicações de faturação.
A par destes desenvolvimentos concretos, investimos uma importante percentagem de tempo dos nossos recursos em investigação, principalmente em plataformas móveis alternativas, no sentido de as avaliar quanto à sua adequabilidade para cenários “Line of business”.


2013 começa por marcar o reforço da equipa de desenvolvimento da moving2u com mais um elemento, de modo a acelerarmos o time-to-market de novas soluções e podermos ainda assim regir a solicitações de projectos por medida. 2013 será também o ano em que as decisões de incorporação de equipamentos de consumo nas organizações passará a uma nova etapa no seu amadurecimento, em que o Windows Embedded Handheld 6.5 continuará a ser a principal opção em termos de terminais robustos mas com a concorrência crescente do Android, esperando que o Windows Embedded Handheld 8, do qual se esperam mais detalhes a serem anunciados em Janeiro pela Microsoft, chegue igualmente a esse segmento de mercado.


A par da minha atividade profissional, recebi pela 10ª vez consecutiva o título de MVP pela Microsoft, esperando que 2013 volte a ter por parte desta um investimento na “mobilidade profissional” e nos eventos técnicos como acontecia até alguns anos atrás. Noutro campo, mais uma vez fiz menos km fora de estrada com o Discovery do que aquilo que gostaria, esperando que também nesse domínio 2013 seja melhor, e no domínio mais pessoal, não obstante 2012 ter sido o ano em que mais pessoas próximas de nós nos deixaram, tivemos excelentes momentos passados em família, seja em férias, seja nos momentos mais casuais.


Espero que 2013 vos traga um bom ano a todos, que o desemprego não se cruze convosco e que mantenham a atitude de mangas arregaçadas a nível profissional e também pessoal, para que não tenham nada a lamentar no final deste ano que agora se inicia.

O meu novo e inesperado gadget – ou "o Alberto tem um tablet Android"

 


Há mais de um ano que temos um iPad 2 na empresa que utilizo ocasionalmente em situações onde não se justifica – ou não convém – levar o PC, como um ou noutro fim de semana ou  em deslocações mais prolongadas. Um exemplo foi a minha última ida ao MVP Global Summit em Seattle em Fevereiro passado, em que me muni apenas do meu LG E900 com Windows Phone 7.5 e do iPad2, e em que dependi desses 2 equipamentos, sem ter sentido falta do PC. A par da minha utilização do iPad, as minhas filhas também se ambientaram rapidamente ao equipamento e não conseguia deixar de apreciar a naturalidade da mais nova de 4 anos a fechar aplicações ou alternar entre elas com os gestos com as mãozitas dela no ecrã.


Antes desta minha experiência com o iPad, já há muitos anos que apreciava o conceito tablet com sistema operativo Windows, desde o XP Tablet Edition. É um facto que o sistema operativo em si não estava orientado a esse tipo de utilização, mas algumas aplicações exploravam muito bem o conceito, nomeadamente o OneNote que permitia tirar notas manuscritas – e guardá-las nesse formato – e depois pesquisar palavras nessas notas. Escusam de tentar com qualquer iPad.


Convencido da utilidade desta nova geração de tablets, era com expetativa que aguardava o Windows 8, em particular as versões RT e tinha decidido que até ao final de 2012 compraria um tablet para utilização pessoal. A expetativa compreendia as vertentes da usabilidade – em que convence – e também do preço e disponibilidade.


Como alguns saberão, gosto muito de fazer todo o terreno com o meu Discovery, e “desde sempre” que utilizo equipamentos móveis  para navegação em fora de estrada. Comecei com PDAs PocketPC e Windows Mobile, com GPS externos por bluetooth, e com o OziExplorerCE, depois passei para o CompeGPS PocketLand, e mais recentemente adquiri o TwoNav. Na vertente PDA usei durante algum tempo o iMate Jasjar, pelo ecrã VGA e pelo teclado, mas andava à procura de um HTC Advantage a bom preço para ter uma solução com ecrã maior e GPS incorporado. Nos últimos tempos desenhava-se a ideia de em vez de gastar 150 a 200€ num Advantage usado, comprar um tablet Android, o mais barato que tivesse GPS ou com Bluetooth, exclusivamente para usar com o TwoNav no jipe.


Em meados de Dezembro, para validar um cenário em termos de desenvolvimento, adquirimos um tablet Samsung de 7″ e Android 4.0. Não lhe liguei nenhuma até ao último fim de semana do ano em que o levei para casa para experimentar.


Não vou dizer que foi uma epifania ou que vi a luz. Mas em 2 dias fiquei rendido ao conceito de tablet de 7″ pela conveniência, e mais uma vez as pequenitas avalizaram o equipamento, pela vertente de jogos (desde que tivesse o TempleRun a que estavam habituadas no iPad…). No dia 31 encontrei o João Cardoso online, e como sabia que ele tinha um Nexus 7 estive a partilhar a experiência do fim de semana com ele e acabei convencido e a ir a correr comprar à Fnac de Coimbra o último Nexus 7 de 32Gb que tinham! Conseguia assim com 249€ comprar um equipamento útil no dia-a-dia, que podia utilizar no jipe e que serve para entreter as minhas filhas.


A escolha no Nexus deveu-se às características de hardware do equipamento e a ter na versão de Android 4.2.1 a possibilidade de ter perfis de utilizador no equipamento, funcionalidade que só encontrava no Windows 8 e que o iPad não inclui. A escolha ficou facilitada pela diferença de preço para o iPad Mini e para os poucos equipamentos Windows 8 RT disponíveis em Portugal à data.


4 dias depois estou satisfeito com o Nexus 7, conto na próxima ida ao estrangeiro levá-lo em vez do iPad, e não tenho problema em admitir que o Android 4.x em tablets me surpreendeu positivamente. No entanto, se as aplicações em equipamentos Android correm tão bem quanto no iPad, é um facto inquestionável que o sistema operativo em si não é tão polido como o iOS, e que gestos standardizados para alternar entre aplicações seriam bem-vindos. Além disso, não me lembro de alguma vez ter tido algum erro de uma aplicação nativa no iPad 2 (que está com iOS), mas com o Nexus, a aplicação de Settings já “rebentou” uma vez, e a aplicação de relógio do sistema operativo “rebenta” frequentemente.  Também me chocou não conseguir adicionar as minhas contas de Office 365 pessoal e da empresa, sem ter de indicar manualmente o endereço do servidor – no Windows Phone 7 e no iPad essas definições são recuperadas automaticamente, bem como tentar adicionar uma conta de email Live da minha filha, obter uma mensagem a dizer para aguardar, que o download começaria em breve, e horas depois continuar na mesma, ate descobrir por uma pesquisa na internet, que há um setting que tinha de ser alterado para esse efeito.


Antes que comecem a questionar se “this is the Alberto that I used to know”, sim, sim é o mesmo! Acreditem que foi preciso uma abertura de espírito muito maior para adoptar o Windows CE em 1999 e os seus derivados nos anos seguintes, em contraciclo com as opções politicamente correctas da altura, como os PalmPilot ou o Apple Newton, e parafraseando uma frase muito batida há uns anos, sempre tentei seguir o mote de “não negue à partida uma ciência que não conhece”! A adopção de um tablet Android não representa para mim nenhuma viragem, simplesmente admito que pelas razões apresentadas acima me pareceu a escolha mais acertada, e com a utilização dessa plataforma poderei tomar decisões mais fundamentadas sobre a viabilidade da plataforma para o desenvolvimento de aplicações profissionais, a par do que temos vindo a fazer com o iOS.


Quanto ao desenvolvimento de aplicações a título pessoal, vou continuar focado no Windows 8 e Windows Phone 8. Como dizia alguém no Twitter, Objective C é pior que Euskera (basco) e Java para mim só é sinónimo de café :)

Conversão de máquinas reais em VM – Experiência pessoal com final feliz

Sempre que troco de computador, para além do processo de passagem de informação para o substituto, tenho por hábito virtualizar o antigo, salvaguardando alguma configuração, ficheiro ou aplicação que não tenha migrado para o novo, seja por opção, seja por esquecimento. Um exemplo é a VM que tenho com uns 6 anos onde ainda tenho o Visual Studio 2003.


Para o efeito costumo usar o VMWare Converter Standalone (gratuito) - a minha preferência pelos produtos VMWare deriva da maior facilidade em mapear portas USB para as VM, em concreto para fazer debug para devices, razão pela qual adquirimos licenças de VMWare Workstation – que cria uma VM funcional a partir da máquina real em execução, o chamado Physical To Virtual (P2V). Abrindo essa VM no VMWare Player (gratuito) ou no VMWare Workstation podemos utilizá-la praticamente como se fosse na máquina real.


O processo de criação das VM no entanto nem sempre é trivial, pois o hardware virtualizado difere necessariamente da máquina física a partir a qual a VM foi criada, pelo que para minimizar a possibilidade da VM não arrancar, há alguns cuidados a observar, como desinstalar o antivírus, remover algum hardware do device manager como controladores RAID e outro hardware que não constará na máquina vitualizada e parar serviços Windows e aplicações em execução. Tal como é esperado, dada a diversidade de configurações de hardware, não há uma lista “completa” do que deve ser feito antes do P2V. Além destes cuidados, ter em atenção o espaço ocupado pelas aplicações e ficheiros, pois quanto menor for esse espaço, mais rápido é o processo de P2V e mais pequenos são os discos “virtuais”. Um exemplo, tipicamente desinstalo o SQL Server e o Office, e removo as bases de dados, backups e ficheiros do Outlook, o que permite “poupar” umas dezenas de GB no disco. Esta página apesar de ser sobre o Disk2VHD, tem informação útil sobre este processo independentemente da ferramenta de virtualização.


Apesar de toda esta teoria, desta vez tive uma dificuldade especial em converter o meu Tecra S11 para VM. A máquina tinha duas partições “utilizáveis” de origem, uma com o Windows 7 original, e outra onde tinha instalado o Windows 8 Pro. Além destas partições, tinha outras duas, uma penso que com a informação de boot, e outra que assumo que tivesse os ficheiros de recuperação da Toshiba.


Como tal, apesar de só querer virtualizar a partição com Windows 7, tinha de virtualizar o disco todo, mas as diversas tentativas com o VMWare Converter resultaram sempre em erro na parte final da conversão. Apesar desse erro, o disco (.vmdk) e a informação da VM (.vmx) eram criados, mas sempre que tentava arrancar a VM com o VMWare Workstation 9 e escolhia o Windows 7, obtinha um BSOD (ecrã azul) e o sistema operativo não arrancava. Tentei start mode, automatic recovery, uma série de outras coisas, sem sucesso e de cada vez que voltava a fazer o P2V eliminava mais drivers mas sempre com o mesmo desfecho. Curiosidade: o Windows 8 corria na perfeição na VM mas não era o que eu pretendia…


Dado que não conseguia avançar por esta via, experimentei o Disk2VHD da SysInternals, que gerou o VHD que depois tentei abrir com o Hyper-V, mas sem sucesso, a VM nunca arrancava, dava logo um problema de boot. Experimentei “montar” o ISO do Windows 7 como CD e arrancar a partir deste para aceder às ferramentas de recuperação, mas nunca consegui com os diversos comandos que testei (BCDBOOT.exe, BCDEDIT.exe, …) que a VM arrancasse de todo, pelo que voltei ao VMWare Converter.


Decidido a resolver o problema, capturei o ecrã azul do arranque do Windows 7 e comecei a pesquisar na internet pelos códigos de erro apresentados. O código STOP: 0x0000007B denunciava um problema com o dispositivo de boot, que podia ser a falta de um driver, corrupção ou um vírus de baixo-nível… cruzando o erro com o VMWare, começaram a aparecer coisas mais concretas, e esta página referia uma situação concreta que fazia sentido. No entanto, para aplicar a sugestão teria de ter uma VM com o mesmo sistema operativo (Windows 7 x64) de onde copiar um pedaço do registry, mas só tinha VMs com Windows 7 de 32 bit, que achei melhor não utilizar pelos diferentes nomes nos respectivos drivers. Caso tivesse essa VM, bastaria a priori copiar o tal ramo do registry, importá-lo para a minha máquina Windows 7 real, e voltar a correr o processo de P2V com o VMWare Converter e já não seria esperado obter o tal erro que obtinha sempre na parte final da conversão.


Já mentalizado para a necessidade de criar uma VM com Windows 7 x64 para poder importar o tal ramo do registry, continuei com algumas pesquisas, fiz algumas experiências que não tiveram sucesso, até que encontrei esta página que mencionava um registry hack, que a não ser suficiente, teria de ser complementado com a edição do ficheiro da VM (.vmx). Dado que o referido hack ao registry não produziu efeito, fiz as alterações sugeridas ao ficheiro .VMX e reiniciei a VM. Certamente por causa dessa alteração a VM demorou muito mais tempo a arrancar do que o esperado, mas ao fim de uns minutos, finalmente arrancou!!!


Em resumo, ao fim de 2 ou 3 semanas encontrei uma solução que podia ter aplicado logo que a primeira conversão falhou, razão pela qual publico este post, que espero que possa revelar-se útil para outros.


 

10º título consecutivo de MVP!

É com muita alegria que partilho que acabei de receber o meu 10º título de MVP atribuído pela Microsoft, agora na categoria Windows Embedded!

Nem parece que já passaram 9 anos sobre o convite feito pelo Nuno Costa, na altura em que a .NET Compact Framework 1.0 dava os primeiros passos com o lançamento do Visual Studio 2003, tendo tido a oportunidade ao longo destes anos de participar em vários eventos enquanto orador e em comunidade de discussão online sempre com o tema do papel que as aplicações móveis podem ter nas empresas e as mais valias em utilizar as sucessivas versões da .NET Compact Framework e do Windows Mobile.

Passados estes 9 anos, continuo ligado profissionalmente ao desenvolvimento de aplicações para dispositivos móveis, com a diferença do foco já não se limitar à oferta da Microsoft e se ter alargado às plataformas de consumo da Apple e da Google. O meu objectivo para os próximos 12 meses é de partilhar as minhas experiências em torno destes tema e continuar disponível para em espaços de discussão ou directamente discutir questões pertinentes ao desenvolvimento de aplicações LOB para dispositivos móveis.

Obrigado a todos que me têm apoiado ao longo desta quase-década e assim me têm permitido ver este meu trabalho reconhecido pela Microsoft e um obrigado especial à minha MVP Lead, Cristina Herrero Smile

Divisão de inteiros em VB.net vs. C#

Imaginem a seguinte instrução em VB.net:

Dim x as integer = 5 / 20 * 100

E em C#:

int x = 5 / 20 * 100;

Seria de esperar que ambas atribuíssem o mesmo resultado a x, no entanto verifica-se que em VB.net é atribuído a x o valor esperado de 25, mas em C#, x fica com o valor zero.

A diferença de resultados resulta do C# reduzir de imediato o resultado da divisão 5 / 20 a um inteiro, de onde resulta o valor 0 que absorve a multiplicação por 100.

Se mudarmos em C# para:

int x = 5M / 20M * 100;

int y = 5 / 20M * 100;

int z = 5M / 20 * 100;

Qualquer uma das variáveis x, y e z fica com o valor 25. Da mesma forma, no seguinte caso…

int a = 5;

int b = 20;

int c = a / b * 100;

c fica de novo com o valor zero, será necessário algo como…

int c = (int)((decimal)a / b * 100);

…para que c fique com o valor esperado de 25.

Mais do que alimentar guerras VB.net/C#, espero que este post sirva para alertar deste comportamento que não podemos classificar de incorrecto por parte do C# mas que pode provocar resultados inesperados  e nem sempre fáceis de detectar…

Época de inventários & balanços

Mais uma vez fui surpreendido pelo final de mais um ano, é difícil acreditar que já passou mais um ano, em que tanta coisa ficou por concretizar!

A velocidade com que o ano passou está intimamente ligada à quantidade de trabalho que fomos mantendo na empresa – parte to qual ainda transita para 2012 – e que comprometeu outras coisas que gostava de ter feito em 2011, como aplicações ‘pessoais’ para Windows Phone 7, brincar com o Netduino, fazer mais (leia-se, algum…) TT com o Discovery e ter mais tempo para as minhas meninas.

Do ponto de vista da moving2u estamos na recta final de entrega do maior projecto que desenvolvemos até hoje, que começámos a desenvolver no final de 2010 e que brevemente estará nas mãos de até 3000 utilizadores na Península Ibérica, colaboradores de uma empresa espanhola que nos confiou tal desafio. Paralelamente fomos desenvolvendo outros projectos específicos, uns mais complexos, como a interessante solução de logística que estamos a ultimar, outros mais simples mas não menos satisfatórios, como a aplicação para controlo de entradas para a Last2Ticket. Demos ainda neste último trimestre os primeiros passos num projecto que visa uma das mais importantes cadeias retalhistas em Portugal. A par destes projectos mais específicos, o nosso produto bandeira, o m2uMobileSales, continuou o seu percurso no território nacional e começa a ser promovido em Angola, Cabo Verde e Moçambique. O elo entre todos estes projectos é a plataforma onde todos correm – e continuarão a correr durante anos – vista por muitos e pelo mercado como ‘moribunda’, mas que tecnicamente, seja do ponto de vista do desenvolvimento, das funcionalidades expostas aos utilizadores e da gestão está num nível diferentes das plataformas móveis de consumo da moda. Estamos a falar (como é óbvio para quem segue o meu blog) do Windows Mobile, agora designado de Windows Embedded Handheld 6.5.

Não obstante o Windows Mobile e a .NET Compact Framework, combinação em que apostámos desde a criação da empresa em 2003, nos ter garantido um volume interessante de trabalho em 2011, “parar é morrer” e não nos podemos dar ao luxo de ignorarmos outras plataformas, que nascendo do mercado do consumo, conquistam um lugar cada vez mais importante nas empresas, pelo que em 2011 encetámos alguns passos no sentido de preparar o maior desafio que teremos em 2012, o abarcar de novas plataformas móveis e de desenvolvimento. É um caminho que nos levantará grandes desafios a diferentes níveis, mas a crer pela excitação na empresa decorrente dessa decisão, posso antecipar que com esforço e dedicação os ultrapassaremos!

Vítima do esforço que a empresa me tem exigido, este blog e outras actividades têm sido relegadas para um plano secundário mas não esquecido Smile

Desejo a todos um óptimo ano de 2012, que recompense aqueles que não baixam os braços, e que possamos estar daqui a um ano a trocar balanços positivos!

Just another Microsoft MVPs site