Portabilidade de um projeto do Tempo de Execução do Windows 8.x para um projeto UWP
Você tem duas opções ao iniciar o processo de portabilidade. Uma delas é editar uma cópia dos arquivos de projeto existentes, incluindo o manifesto do pacote do aplicativo (para essa opção, consulte as informações sobre como atualizar seus arquivos de projeto em Migrar aplicativos para a Plataforma Universal do Windows (UWP)). A outra opção é criar um novo projeto do Windows 10 no Visual Studio e copiar seus arquivos para ele. A primeira seção deste tópico descreve essa segunda opção, mas o restante do tópico tem informações adicionais aplicáveis a ambas as opções. Você também pode optar por manter seu novo projeto do Windows 10 na mesma solução que seus projetos existentes e compartilhar arquivos de código-fonte usando um projeto compartilhado. Ou você pode manter o novo projeto em uma solução própria e compartilhar arquivos de código-fonte usando o recurso de arquivos vinculados no Visual Studio.
Crie o projeto e copie os arquivos para ele
Essas etapas se concentram na opção de criar um novo projeto do Windows 10 no Visual Studio e copiar seus arquivos para ele. Algumas das especificidades sobre quantos projetos você cria e quais arquivos você copia dependerão dos fatores e decisões descritos em Se você tiver um aplicativo Universal 8.1 e as seções que o seguem. Essas etapas assumem o caso mais simples.
- Inicie o Microsoft Visual Studio 2015 e crie um novo projeto de Aplicativo em Branco (Windows Universal). Para obter mais informações, consulte Iniciar seu aplicativo do Tempo de Execução do Windows 8.x usando modelos (C#, C++, Visual Basic). Seu novo projeto cria um pacote de aplicativos (um arquivo appx) que será executado em todas as famílias de dispositivos.
- No projeto de aplicativo Universal 8.1, identifique todos os arquivos de código-fonte e arquivos de ativos visuais que você deseja reutilizar. Usando o Explorador de Arquivos, copie modelos de dados, modelos de exibição, ativos visuais, dicionários de recursos, estrutura de pastas e qualquer outra coisa que você deseja reutilizar para seu novo projeto. Copie ou crie subpastas no disco, conforme necessário.
- Copie exibições (por exemplo, MainPage.xaml e MainPage.xaml.cs) para o novo projeto também. Novamente, crie novas subpastas conforme necessário e remova as visualizações existentes do projeto. Mas, antes de substituir ou remover um modo de exibição gerado pelo Visual Studio, mantenha uma cópia, pois pode ser útil consultá-lo mais tarde. A primeira fase da portabilidade de um aplicativo Universal 8.1 se concentra em fazer com que ele tenha uma boa aparência e funcione bem em uma família de dispositivos. Mais tarde, você voltará sua atenção para garantir que as exibições se adaptem bem a todos os fatores forma e, opcionalmente, para adicionar qualquer código adaptável para obter o máximo de uma família de dispositivos específica.
- No Gerenciador de Soluções, verifique se Mostrar Todos os Arquivos está ativado. Selecione os arquivos que você copiou, clique com o botão direito do mouse neles e clique em Incluir no projeto. Isso incluirá automaticamente as pastas que as contêm. Você pode desativar Mostrar todos os arquivos, se desejar. Um fluxo de trabalho alternativo, se preferir, é usar o comando Adicionar Item Existente, tendo criado todas as subpastas necessárias no Gerenciador de Soluções do Visual Studio. Verifique novamente se os ativos visuais têm a Ação de Build definida como Conteúdo e a Cópia para o diretório de saída definida como Não copiar.
- É provável que você veja alguns erros de compilação neste estágio. Mas, se você souber o que precisa alterar, poderá usar o comando Localizar e Substituir do Visual Studio para fazer alterações em massa no código-fonte; e no editor de código imperativo no Visual Studio, use os comandos Resolver e Organizar Usos no menu de contexto para alterações mais direcionadas.
Maximizando a marcação e a reutilização de código
Você descobrirá que refatorar um pouco e/ou adicionar código adaptável (que é explicado abaixo) permitirá maximizar a marcação e o código que funciona em todas as famílias de dispositivos. Aqui estão mais detalhes.
- Os arquivos comuns a todas as famílias de dispositivos não precisam de consideração especial. Esses arquivos serão usados pelo aplicativo em todas as famílias de dispositivos em que ele é executado. Isso inclui arquivos de marcação XAML, arquivos de código-fonte imperativos e arquivos de ativos.
- É possível que seu aplicativo detecte a família de dispositivos em que está sendo executado e navegue até uma exibição que foi projetada especificamente para essa família de dispositivos. Para obter mais detalhes, consulte Detectando a plataforma em que seu aplicativo está sendo executado.
- Uma técnica semelhante que você pode achar útil se não houver alternativa é dar a um arquivo de marcação ou arquivo ResourceDictionary (ou a pasta que contém o arquivo) um nome especial de modo que ele seja carregado automaticamente em tempo de execução somente quando seu aplicativo for executado em uma família de dispositivos específica. Essa técnica é ilustrada no estudo de caso Bookstore1.
- Você deve ser capaz de remover muitas das diretivas de compilação condicional no código-fonte do seu aplicativo Universal 8.1 se precisar apenas dar suporte ao Windows 10. Consulte Compilação condicional e código adaptável neste tópico.
- Para usar recursos que não estão disponíveis em todas as famílias de dispositivos (por exemplo, impressoras, scanners ou o botão da câmera), você pode escrever código adaptável. Consulte o terceiro exemplo em Compilação condicional e código adaptável neste tópico.
- Se você quiser dar suporte ao Windows 8.1, Windows Phone 8.1 e Windows 10, poderá manter três projetos na mesma solução e compartilhar código com um projeto compartilhado. Como alternativa, você pode compartilhar arquivos de código-fonte entre projetos. Veja como: no Visual Studio, clique com o botão direito do mouse no projeto no Gerenciador de Soluções, selecione Adicionar Item Existente, selecione os arquivos a serem compartilhados e clique em Adicionar como Link. Armazene seus arquivos de código-fonte em uma pasta comum no sistema de arquivos onde os projetos vinculados a eles possam vê-los. E não se esqueça de adicioná-los ao controle do código-fonte.
- Para reutilização no nível binário, em vez do nível do código-fonte, consulte Criando componentes do Tempo de Execução do Windows em C# e Visual Basic. Há também Bibliotecas de Classes Portáteis, que dão suporte ao subconjunto de APIs do .NET que estão disponíveis nos aplicativos do .NET Framework para Windows 8.1, Windows Phone 8.1 e Windows 10 (.NET Core) e no .NET Framework completo. Os assemblies da Biblioteca de Classes Portáteis são compatíveis com binários com todas essas plataformas. Use o Visual Studio para criar um projeto direcionado a uma Biblioteca de Classes Portátil. Consulte Desenvolvimento multiplataforma com a Biblioteca de Classes Portátil.
SDKs de extensão
A maioria das APIs do Tempo de Execução do Windows que seu aplicativo Universal 8.1 já chama é implementada no conjunto de APIs conhecido como família de dispositivos universal. No entanto, alguns são implementados em SDKs de extensão e o Visual Studio reconhece apenas APIs implementadas pela família de dispositivos de destino do aplicativo ou por qualquer SDK de extensão que você tenha referenciado.
Se você receber erros de compilação sobre namespaces, tipos ou membros que não puderam ser encontrados, é provável que essa seja a causa. Abra o tópico da API na documentação de referência da API e navegue até a seção Requisitos: que informará qual é a família de dispositivos de implementação. Se essa não for sua família de dispositivos de destino, para disponibilizar a API para seu projeto, você precisará de uma referência ao SDK de extensão para essa família de dispositivos.
Clique em Projetar>Adicionar Referência de Extensões> Universais>do Windows e selecione o SDK de extensão apropriado. Por exemplo, se as APIs que você deseja chamar estiverem disponíveis apenas na família de dispositivos móveis e tiverem sido introduzidas na versão 10.0.x.y, selecione Extensões do Windows Mobile para a UWP.
Isso adicionará a seguinte referência ao seu arquivo de projeto:
<ItemGroup>
<SDKReference Include="WindowsMobile, Version=10.0.x.y">
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
O nome e o número da versão correspondem às pastas no local instalado do SDK. Por exemplo, as informações acima correspondem a este nome de pasta:
\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsMobile\10.0.x.y
A menos que seu aplicativo tenha como destino a família de dispositivos que implementa a API, você precisará usar a classe ApiInformation para testar a presença da API antes de chamá-la (isso é chamado de código adaptável). Essa condição será avaliada sempre que seu aplicativo for executado, mas só será avaliada como verdadeira em dispositivos em que a API está presente e, portanto, disponível para chamada. Use SDKs de extensão e código adaptável somente depois de verificar se existe uma API universal. Alguns exemplos são dados na seção abaixo.
Além disso, consulte Manifesto do pacote do aplicativo.
Compilação condicional e código adaptável
Se você estiver usando a compilação condicional (com diretivas de pré-processador C#) para que seus arquivos de código funcionem no Windows 8.1 e no Windows Phone 8.1, agora você pode examinar essa compilação condicional à luz do trabalho de convergência feito no Windows 10. Convergência significa que, em seu aplicativo do Windows 10, algumas condições podem ser removidas completamente. Outros mudam para verificações de tempo de execução, conforme demonstrado nos exemplos abaixo.
Observação Se você quiser dar suporte ao Windows 8.1, Windows Phone 8.1 e Windows 10 em um único arquivo de código, também poderá fazer isso. Se você examinar seu projeto do Windows 10 nas páginas de propriedades do projeto, verá que o projeto define WINDOWS_UAP como um símbolo de compilação condicional. Então, você pode usar isso em combinação com WINDOWS_APP e WINDOWS_PHONE_APP. Esses exemplos mostram o caso mais simples de remover a compilação condicional de um aplicativo Universal 8.1 e substituir o código equivalente por um aplicativo Windows 10.
Este primeiro exemplo mostra o padrão de uso da API PickSingleFileAsync (que se aplica somente ao Windows 8.1) e da API PickSingleFileAndContinue (que se aplica somente ao Windows Phone 8.1).
#if WINDOWS_APP
// Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync
#else
// Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAndContinue
#endif // WINDOWS_APP
Windows 10 converge para a API PickSingleFileAsync , portanto, seu código simplifica isso:
// Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync
Neste exemplo, lidamos com o botão Voltar do hardware, mas apenas no Windows Phone.
#if WINDOWS_PHONE_APP
Windows.Phone.UI.Input.HardwareButtons.BackPressed += this.HardwareButtons_BackPressed;
#endif // WINDOWS_PHONE_APP
...
#if WINDOWS_PHONE_APP
void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
// Handle the event.
}
#endif // WINDOWS_PHONE_APP
No Windows 10, o evento do botão Voltar é um conceito universal. Os botões Voltar implementados no hardware ou no software gerarão o evento BackRequested , portanto, é esse o único a ser manipulado.
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested +=
this.ViewModelLocator_BackRequested;
...
private void ViewModelLocator_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
{
// Handle the event.
}
Este exemplo final é semelhante ao anterior. Aqui, lidamos com o botão da câmera de hardware, mas, novamente, apenas no código compilado no pacote de aplicativos do Windows Phone.
#if WINDOWS_PHONE_APP
Windows.Phone.UI.Input.HardwareButtons.CameraPressed += this.HardwareButtons_CameraPressed;
#endif // WINDOWS_PHONE_APP
...
#if WINDOWS_PHONE_APP
void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
// Handle the event.
}
#endif // WINDOWS_PHONE_APP
No Windows 10, o botão da câmera de hardware é um conceito específico da família de dispositivos móveis. Como um pacote de aplicativo estará em execução em todos os dispositivos, alteramos nossa condição de tempo de compilação para uma condição de tempo de execução usando o que é conhecido como código adaptável. Para fazer isso, usamos a classe ApiInformation para consultar em tempo de execução a presença da classe HardwareButtons. HardwareButtons é definido no SDK da extensão móvel, portanto, precisaremos adicionar uma referência a esse SDK ao nosso projeto para que esse código seja compilado. Observe, porém, que o manipulador só será executado em um dispositivo que implemente os tipos definidos no SDK da extensão móvel, e essa é a família de dispositivos móveis. Portanto, esse código é moralmente equivalente ao código Universal 8.1, pois tem o cuidado de usar apenas recursos que estão presentes, embora consiga isso de uma maneira diferente.
// Note: Cache the value instead of querying it more than once.
bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent
("Windows.Phone.UI.Input.HardwareButtons");
if (isHardwareButtonsAPIPresent)
{
Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
this.HardwareButtons_CameraPressed;
}
...
private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
// Handle the event.
}
Além disso, consulte Detectando a plataforma em que seu aplicativo está sendo executado.
Manifesto do pacote do aplicativo
O tópico O que mudou no Windows 10 lista as alterações na referência de esquema de manifesto do pacote para Windows 10, incluindo elementos que foram adicionados, removidos e alterados. Para obter informações de referência sobre todos os elementos, atributos e tipos no esquema, consulte Hierarquia de elementos. Se você estiver portando um aplicativo da Loja do Windows Phone ou se seu aplicativo for uma atualização para um aplicativo da Loja do Windows Phone, verifique se o elemento mp:PhoneIdentity corresponde ao que está no manifesto do aplicativo anterior (use os mesmos GUIDs que foram atribuídos ao aplicativo pela Loja). Isso garantirá que os usuários do seu aplicativo que estão atualizando para o Windows 10 ou Windows 11 recebam seu novo aplicativo como uma atualização, não uma duplicata. Consulte o tópico de referência mp:PhoneIdentity para obter mais detalhes.
As configurações em seu projeto (incluindo quaisquer referências de SDKs de extensão) determinam a área de superfície da API que seu aplicativo pode chamar. No entanto, o manifesto do pacote do aplicativo é o que determina o conjunto real de dispositivos nos quais seus clientes podem instalar seu aplicativo na Loja. Para obter mais informações, consulte exemplos em TargetDeviceFamily.
Você pode editar o manifesto do pacote do aplicativo para definir várias declarações, recursos e outras configurações necessárias para alguns recursos. Você pode usar o editor de manifesto do pacote do aplicativo Visual Studio para editá-lo. Se o Gerenciador de Soluções não for mostrado, escolha-o no menu Exibir . Clique duas vezes em Package.appxmanifest. Isso abre a janela do editor de manifesto. Selecione a guia apropriada para fazer alterações e salve.
O próximo tópico é Solução de problemas.