Adicionar um comando de menu contextual do Explorador de Ficheiros a uma aplicação de ambiente de trabalho empacotada

As aplicações do Windows 11 estendem o menu contextual moderno do Explorador de Ficheiros implementando o IExplorerCommand e registando o comando com a identidade da aplicação. Isto aplica-se a aplicações de ambiente de trabalho empacotadas e a aplicações Win32 não empacotadas que usam um pacote esparso.

Uma associação de tipos de ficheiro pode disponibilizar uma aplicação em Open com ou adicionar um verbo de edição para um tipo de ficheiro que a aplicação gere. Não fornece a extensão do menu de contexto de uso geral descrita neste artigo. Para adicionar um comando para ficheiros, pastas ou fundos de pasta arbitrários, use IExplorerCommand.

Para o design do menu contextual do Windows 11 e orientações sobre quando adicionar um comando, veja Estender o Menu de Contexto e o Diálogo de Partilha no Windows 11.

Como funcionam as extensões dos menus de contexto

Uma extensão de menu contextual tem estas partes:

  1. Uma DLL nativa implementa uma ou mais classes COM que expõem IExplorerCommand.
  2. O manifesto do pacote regista cada classe COM como uma windows.comServer extensão.
  3. O manifesto do pacote regista o comando como uma windows.fileExplorerContextMenus extensão e associa um tipo de item shell ao CLSID da classe COM.

O File Explorer ativa a classe COM quando constrói o menu de contexto. A sua IExplorerCommand implementação fornece o título, ícone, estado e ação. Os comandos da mesma aplicação podem ser agrupados num menu desdobrável associado à aplicação; implemente EnumSubCommands para fornecer comandos subordinados.

Important

O Explorador de Ficheiros carrega código de extensão shell como parte da experiência do shell. Assegure que GetTitle, GetIcon, GetState e outros métodos de construção de menus sejam rápidos. Não realize trabalhos dispendiosos no caminho da interface do Explorador de Ficheiros. Execute operações mais longas após Invoke ser chamado.

Implementar IExplorerCommand

Implementa IExplorerCommand numa DLL COM nativa. C++ é a escolha habitual porque o comando corre no caminho de integração do Shell. A implementação abreviada seguinte fornece um título de comando, ativa o comando e recebe os itens selecionados quando o utilizador o invoca.

class EditCommand final : public IExplorerCommand
{
public:
    IFACEMETHODIMP GetTitle(IShellItemArray*, PWSTR* title)
    {
        return SHStrDup(L"Edit with Contoso", title);
    }

    IFACEMETHODIMP GetState(
        IShellItemArray*, BOOL, EXPCMDSTATE* state)
    {
        *state = ECS_ENABLED;
        return S_OK;
    }

    IFACEMETHODIMP Invoke(IShellItemArray* items, IBindCtx*)
    {
        // Obtain selected items from items and start the app or operation.
        return S_OK;
    }

    IFACEMETHODIMP GetIcon(IShellItemArray*, PWSTR* icon)
    {
        return SHStrDup(L"ContosoCommand.dll,-101", icon);
    }

    IFACEMETHODIMP GetToolTip(IShellItemArray*, PWSTR* tooltip)
    {
        *tooltip = nullptr;
        return E_NOTIMPL;
    }

    IFACEMETHODIMP GetCanonicalName(GUID* canonicalName)
    {
        *canonicalName = GUID_NULL;
        return S_OK;
    }

    IFACEMETHODIMP GetFlags(EXPCMDFLAGS* flags)
    {
        *flags = ECF_DEFAULT;
        return S_OK;
    }

    IFACEMETHODIMP EnumSubCommands(IEnumExplorerCommand** commands)
    {
        *commands = nullptr;
        return E_NOTIMPL;
    }
};

Utilize o IShellItemArray passado a Invoke para enumerar a seleção atual. GetState pode devolver estados como ECS_HIDDEN, ECS_DISABLED, ou ECS_ENABLED controlar se o comando aparece e pode ser selecionado. Para o contrato completo, veja IExplorerCommand.

Atribuir um CLSID à classe COM e garantir que o mesmo CLSID é usado no manifesto do pacote. Por exemplo:

class __declspec(uuid("01234567-89AB-CDEF-0123-456789ABCDEF"))
    EditCommand;

Registar o comando no manifesto do pacote

Declare os espaços de nomes com, desktop4 e desktop5 no elemento raiz Package e adicione-os a IgnorableNamespaces.

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
  IgnorableNamespaces="com desktop4 desktop5">
  <!-- ... -->
</Package>

No elemento de aplicação Extensions , regista primeiro a DLL como servidor COM. com:Class/@Id é o CLSID do comando, e Path é o caminho relativo ao pacote da DLL.

<com:Extension Category="windows.comServer">
  <com:ComServer>
    <com:SurrogateServer DisplayName="Contoso commands">
      <com:Class
        Id="01234567-89AB-CDEF-0123-456789ABCDEF"
        Path="ContosoCommand.dll"
        ThreadingModel="STA" />
    </com:SurrogateServer>
  </com:ComServer>
</com:Extension>

Depois associe o CLSID ao contexto em que o comando deve aparecer.

<desktop4:Extension Category="windows.fileExplorerContextMenus">
  <desktop4:FileExplorerContextMenus>
    <desktop5:ItemType Type="*">
      <desktop5:Verb
        Id="EditWithContoso"
        Clsid="01234567-89AB-CDEF-0123-456789ABCDEF" />
    </desktop5:ItemType>
  </desktop4:FileExplorerContextMenus>
</desktop4:Extension>

desktop5:ItemType/@Type identifica os itens do shell de destino. Use * para ficheiros, Directory para pastas selecionadas ou Directory\Background para o fundo de uma pasta. Pode registar múltiplas ItemType entradas para o mesmo CLSID quando um comando suporta múltiplos contextos.

O desktop5:Verb/@Id identifica o registo de manifesto. desktop5:Verb/@Clsid deve corresponder ao com:Class/@Id valor e ao CLSID da classe COM.

Para o esquema completo do manifesto, consulte desktop4:FileExplorerContextMenus e com:Class.

Criar o pacote da DLL

Inclua a DLL de comandos e quaisquer recursos que requer no pacote no caminho especificado por com:Class/@Path. Se utilizar um projeto de empacotamento de aplicações do Windows, adicione a DLL ao projeto e configure-a para ser copiada para a saída do pacote. Configure uma dependência de compilação ou cópia pós-compilação para que o pacote contenha a DLL atual.

A arquitetura DLL deve corresponder à arquitetura do Explorador de Ficheiros que a carrega. Construa e empacote a arquitetura apropriada para o dispositivo alvo.

Use um pacote simples para uma aplicação não empacotada

Uma aplicação Win32 não empacotada pode usar o mesmo IExplorerCommand e manifestar registos instalando um pacote esparso que dá identidade ao pacote da aplicação. Um pacote esparso não contém os binários da aplicação; Refere-se antes à aplicação instalada externamente.

Para além das extensões COM e do menu de contexto mostradas anteriormente, um manifesto de pacote esparso normalmente declara uap10:AllowExternalContent e configura a aplicação como uma aplicação Win32. O exemplo seguinte mostra as declarações de pacotes esparsos relevantes.

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap10 rescap">

  <Properties>
    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
  </Properties>

  <Applications>
    <Application
      Id="ContosoApp"
      Executable="ContosoApp.exe"
      uap10:TrustLevel="mediumIL"
      uap10:RuntimeBehavior="win32App">
      <!-- VisualElements and the COM/context-menu Extensions go here. -->
    </Application>
  </Applications>

  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources" />
  </Capabilities>
</Package>

Consulte os pacotes esparsos para conhecer os requisitos de empacotamento e registo das aplicações não embaladas.

Testar a extensão

Instale ou registe-se o pacote, depois abra o Explorador de Ficheiros e clique com o botão direito num item que corresponda a um dos tipos de itens registados. Se o comando não aparecer após instalar ou atualizar um pacote, reinicie o Explorador de Ficheiros ou saia e volte a entrar para que o shell recarregue o registo da extensão.

Use Mostrar mais opções apenas para inspecionar extensões legadas do menu contextual. Um comando registado através de windows.fileExplorerContextMenus e implementado com IExplorerCommand aparece no menu de contexto do Windows 11.

Associações de tipos de ficheiro

Registe uma associação de tipo de ficheiro ao abrir ou editar esse tipo de ficheiro. Pode disponibilizar a aplicação através de Abrir com e adicionar um comando de edição aos tipos de ficheiro associados. Use o mecanismo do menu contextual neste artigo para comandos que se aplicam a ficheiros genéricos, pastas ou fundos, ou para comandos que realizam operações sem abrir a experiência normal de abertura de ficheiros da aplicação.