Compartilhar via


Criar um aplicativo Universal do Windows de várias instâncias

Este tópico descreve como criar aplicativos UWP (Plataforma Universal do Windows) de várias instâncias.

Do Windows 10, versão 1803 (10.0; Build 17134) em diante, seu aplicativo UWP pode optar por dar suporte a várias instâncias. Se uma instância de um aplicativo UWP de várias instâncias estiver em execução e uma solicitação de ativação subsequente for exibida, a plataforma não ativará a instância existente. Em vez disso, ele criará uma nova instância, que será executada em um processo separado.

Importante

Há suporte para vários instanciamentos para aplicativos JavaScript, mas o redirecionamento de vários instanciamentos não é suportado. Como não há suporte para redirecionamento de várias instanciadas para aplicativos JavaScript, a classe AppInstance não é útil para esses aplicativos.

Aceitar o comportamento de várias instâncias

Se você estiver criando um novo aplicativo de várias instâncias, poderá instalar o Modelos de Projeto de Aplicativo Multi-Instância.VSIX, disponível no Visual Studio Marketplacedo . Depois de instalar os modelos, eles estarão disponíveis na caixa de diálogo Novo Projeto em Visual C# > Windows Universal (ou Outras Linguagens > Visual C++ > Windows Universal).

Observação

O modelo do Projeto de Aplicativo de Várias Instâncias não está mais disponível. O modelo VSIX era uma conveniência, portanto, você precisará modificar o projeto existente, conforme descrito abaixo. Certifique-se de adicionar a constante DISABLE_XAML_GENERATED_MAIN aos símbolos de build do projeto, pois isso impede que o build gere um Main() padrão. Isso permite o uso de uma versão específica para o aplicativo do Main().

Dois modelos são instalados: aplicativo UWP de várias instâncias, que fornece o modelo para criar um aplicativo de várias instâncias e aplicativo UWP de Redirecionamento de Várias Instâncias, que fornece uma lógica adicional sobre a qual você pode desenvolver para iniciar uma nova instância ou ativar seletivamente uma instância já iniciada. Por exemplo, talvez você queira apenas uma instância de cada vez editando o mesmo documento, de modo que você traga a instância que tem esse arquivo aberto em primeiro plano em vez de iniciar uma nova instância.

Ambos os modelos adicionam SupportsMultipleInstances ao arquivo package.appxmanifest. Observe que o prefixo de namespace desktop4 e iot2: somente projetos destinados ao desktop ou projetos de IoT (Internet das Coisas) suportam múltiplas instâncias.

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"  
  IgnorableNamespaces="uap mp desktop4 iot2">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4:SupportsMultipleInstances="true"
      iot2:SupportsMultipleInstances="true">
      ...
    </Application>
  </Applications>
   ...
</Package>

Redirecionamento de ativação de várias instâncias

O suporte a várias instâncias para aplicativos UWP vai além de simplesmente possibilitar a inicialização de várias instâncias do aplicativo. Ele permite a personalização nos casos em que você deseja selecionar se uma nova instância do seu aplicativo é iniciada ou se uma instância que já está em execução está ativada. Por exemplo, se o aplicativo for iniciado para editar um arquivo que já está sendo editado em outra instância, convém redirecionar a ativação para essa instância em vez de abrir outra instância que já está editando o arquivo.

Para vê-lo em ação, assista a este vídeo sobre a criação de aplicativos UWP de várias instâncias.

O modelo de aplicativo UWP de Redirecionamento de Várias Instâncias adiciona SupportsMultipleInstances ao arquivo package.appxmanifest, conforme mostrado acima, e também adiciona um Program.cs (ou Program.cpp, se você estiver usando a versão C++ do modelo) ao seu projeto que contém uma Main() função. A lógica para redirecionar a ativação vai na função Main. O modelo para Program.cs é mostrado abaixo.

A propriedade AppInstance.RecommendedInstance representa a instância preferencial fornecida pelo shell para essa solicitação de ativação, se houver uma (ou null se não houver uma). Se o shell fornecer uma preferência, você poderá redirecionar a ativação para essa instância ou ignorá-la se quiser.

public static class Program
{
    // This example code shows how you could implement the required Main method to
    // support multi-instance redirection. The minimum requirement is to call
    // Application.Start with a new App object. Beyond that, you may delete the
    // rest of the example code and replace it with your custom code if you wish.

    static void Main(string[] args)
    {
        // First, we'll get our activation event args, which are typically richer
        // than the incoming command-line args. We can use these in our app-defined
        // logic for generating the key for this instance.
        IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs();

        // If the Windows shell indicates a recommended instance, then
        // the app can choose to redirect this activation to that instance instead.
        if (AppInstance.RecommendedInstance != null)
        {
            AppInstance.RecommendedInstance.RedirectActivationTo();
        }
        else
        {
            // Define a key for this instance, based on some app-specific logic.
            // If the key is always unique, then the app will never redirect.
            // If the key is always non-unique, then the app will always redirect
            // to the first instance. In practice, the app should produce a key
            // that is sometimes unique and sometimes not, depending on its own needs.
            string key = Guid.NewGuid().ToString(); // always unique.
                                                    //string key = "Some-App-Defined-Key"; // never unique.
            var instance = AppInstance.FindOrRegisterInstanceForKey(key);
            if (instance.IsCurrentInstance)
            {
                // If we successfully registered this instance, we can now just
                // go ahead and do normal XAML initialization.
                global::Windows.UI.Xaml.Application.Start((p) => new App());
            }
            else
            {
                // Some other instance has registered for this key, so we'll 
                // redirect this activation to that instance instead.
                instance.RedirectActivationTo();
            }
        }
    }
}

Main() é a primeira coisa que é executada. Ele é executado antes de OnLaunched e OnActivated. Isso permite que você determine se deve ativar essa ou outra instância antes que qualquer outro código de inicialização em seu aplicativo seja executado.

O código acima determina se uma instância existente ou nova do aplicativo está ativada. Uma chave é usada para determinar se há uma instância existente que você deseja ativar. Por exemplo, se o aplicativo puder ser iniciado para manipular a ativação de arquivo, você poderá usar o nome do arquivo como uma chave. Em seguida, você pode verificar se uma instância do seu aplicativo já está registrada com essa chave e ativá-la em vez de abrir uma nova instância. Essa é a ideia por trás do código: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Se uma instância registrada com a chave for encontrada, essa instância será ativada. Se a chave não for encontrada, a instância atual (a instância que está em execução Mainno momento) criará seu objeto de aplicativo e começará a ser executada.

Tarefas em segundo plano e instâncias múltiplas

  • Tarefas em segundo plano fora de processo dão suporte a múltiplas instâncias. Normalmente, cada novo gatilho resulta em uma nova instância da tarefa em segundo plano (embora tecnicamente falando várias tarefas em segundo plano possam ser executadas no mesmo processo de host). No entanto, uma instância diferente da tarefa em segundo plano é criada.
  • As tarefas em segundo plano no proc não dão suporte a várias instancamentos.
  • As tarefas de áudio em segundo plano não dão suporte a múltiplas instâncias.
  • Quando um aplicativo registra uma tarefa em segundo plano, ele geralmente verifica primeiro se a tarefa já está registrada e, em seguida, exclui e registra novamente ou não faz nada para manter o registro existente. Esse ainda é o comportamento típico com aplicativos de várias instâncias. No entanto, um aplicativo de várias instâncias pode optar por registrar um nome de tarefa em segundo plano diferente por instância. Isso resultará em vários registros para o mesmo gatilho e várias instâncias de tarefa em segundo plano serão ativadas quando o gatilho for acionado.
  • Os serviços de aplicativo iniciam uma instância separada da tarefa em segundo plano do serviço de aplicativo para cada conexão. Isso permanece inalterado para aplicativos de várias instâncias, ou seja, cada instância de um aplicativo de várias instâncias obterá sua própria instância da tarefa em segundo plano do serviço de aplicativo.

Considerações adicionais

  • Aplicativos UWP que têm como alvo projetos de desktop e Internet das Coisas (IoT) oferecem suporte a várias instâncias.
  • Para evitar problemas de condições de corrida e contenção, os aplicativos de várias instâncias precisam tomar medidas para particionar ou sincronizar o acesso a configurações, armazenamento local do aplicativo e qualquer outro recurso (como arquivos de usuário, um banco de dados e assim por diante) que possam ser compartilhados entre várias instâncias. Mecanismos de sincronização padrão, como mutexes, semáforos, eventos e assim por diante, estão disponíveis.
  • Se o aplicativo tiver SupportsMultipleInstances em seu arquivo Package.appxmanifest, suas extensões não precisarão declarar SupportsMultipleInstances.
  • Se você adicionar SupportsMultipleInstances a qualquer outra extensão, além de tarefas em segundo plano ou serviços de aplicativo, e o aplicativo que hospeda a extensão também não declarar SupportsMultipleInstances em seu arquivo Package.appxmanifest, um erro de esquema será gerado.
  • Os aplicativos podem usar a declaração ResourceGroup em seu manifesto para agrupar várias tarefas em segundo plano no mesmo host. Isso entra em conflito com várias instanciações, em que cada ativação entra em um host separado. Portanto, um aplicativo não pode declarar ambos SupportsMultipleInstances e ResourceGroup em seu manifesto.

Amostra

Veja o exemplo de redirecionamento de ativação de várias instâncias em Multi-Instance sample.

Consulte também

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToManipular ativação do aplicativo