Partilhar via


Criar um Aplicativo Universal do Windows com várias instâncias

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

A partir do Windows 10, versão 1803 (10.0; Build 17134) em diante, seu aplicativo UWP pode optar por oferecer 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 recebida, a plataforma não ativará a instância existente. Em vez disso, ele criará uma nova instância, executada em um processo separado.

Ativar a funcionalidade de múltiplas instâncias

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

Observação

O modelo Multi-Instance App Project não está mais disponível. O modelo VSIX foi uma conveniência, então você precisará modificar o projeto existente, conforme descrito abaixo. Certifique-se de adicionar a constante DISABLE_XAML_GENERATED_MAIN aos símbolos de compilação do projeto, pois isso impede que a compilação gere um Main() padrão. Isso permite o uso de uma versão específica do aplicativo escrita especificamente do Main().

Dois modelos são instalados: aplicativo UWP Multi-Instance, que fornece o modelo para criar um aplicativo de várias instâncias, e aplicativo UWP Multi-Instance Redirection, que fornece lógica adicional na qual você pode aproveitar para executar uma nova instância ou ativar seletivamente uma instância que já foi iniciada. Por exemplo, talvez você queira apenas uma instância de cada vez editando o mesmo documento, para trazer a instância que tem esse arquivo aberto para o primeiro plano em vez de iniciar uma nova instância.

Ambos os modelos adicionam SupportsMultipleInstances ao arquivo package.appxmanifest. Observe o prefixo desktop4 do namespace: somente projetos que visam o desktop suportam multi-instancing.

Observação

Se o seu aplicativo tiver como destino o Windows 10, versão 2004 (Build 19041) ou posterior, você poderá usar o atributo mais recente uap10:SupportsMultipleInstances em vez de desktop4:SupportsMultipleInstances. O uap10 namespace é a abordagem preferida para aplicativos mais recentes.

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  IgnorableNamespaces="uap mp desktop4">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4: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 tornar possível iniciar 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 é ativada. Por exemplo, se o aplicativo for iniciado para editar um arquivo que já está sendo editado em outra instância, talvez você queira redirecionar a ativação para essa instância em vez de abrir outra instância que já esteja editando o arquivo.

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

O modelo de do aplicativo UWP de redirecionamento de várias instâncias adiciona ao arquivo package.appxmanifest, conforme mostrado acima, e também adiciona uma Program.cs (ou Program.cpp, se você estiver usando a versão C++ do modelo) ao seu projeto que contém uma 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 desejar.

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 corre. Ele é executado antes OnLaunched e OnActivated. Isso permite que você determine se deseja ativar esta 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 seu aplicativo está ativada. Uma chave é usada para determinar se há uma instância existente que você deseja ativar. Por exemplo, se a sua aplicação puder ser iniciada para processar a ativação de ficheiro, poderá utilizar o nome do ficheiro 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. Esta é 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á sendo executada Main) 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 do processo suportam multi-instancing. 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 processo não suportam múltiplas instâncias.
  • As tarefas de áudio em segundo plano não suportam múltiplas instâncias.
  • Quando um aplicativo registra uma tarefa em segundo plano, ele geralmente primeiro verifica 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 tarefas 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 terá sua própria instância da tarefa em segundo plano do serviço de aplicativo.

Considerações adicionais

  • A multi-instanciação é suportada por aplicações UWP direcionadas para projetos de desktop.
  • Para evitar condições de corrida e problemas de contenção, os aplicativos de várias instâncias precisam tomar medidas para particionar/sincronizar o acesso às configurações, ao armazenamento local do aplicativo e a qualquer outro recurso (como arquivos do usuário, um armazenamento de dados e assim por diante) que possa ser compartilhado 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 a multi-instanciação, onde cada ativação vai para um anfitrião separado. Portanto, um aplicativo não pode declarar SupportsMultipleInstances e ResourceGroup em seu manifesto.

Exemplo

Consulte o exemplo de várias instâncias em para um exemplo de redirecionamento de ativação de várias instâncias.

Ver também

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