Compartilhar via


C#/WinRT

O C#/WinRT é um kit de ferramentas empacotado em NuGet que fornece suporte à projeção do WinRT (Windows Runtime) para a linguagem C#. Um assembly é um assembly de interoperabilidade que permite programar APIs do WinRT de modo natural e familiar para a linguagem de destino. A projeção do C#/WinRT oculta detalhes de interoperabilidade entre interfaces do C# e do WinRT e fornece mapeamentos de vários tipos do WinRT para equivalentes apropriados do .NET, como cadeias de caracteres, URIs, tipos de valores comuns e coleções genéricas.

O C#/WinRT atualmente fornece suporte para o consumo de APIs do WinRT por meio do uso de TFMs (Monikers da Estrutura de Destino) no .NET. Definir o TFM com uma versão específica do SDK do Windows adiciona referências à projeção do SDK do Windows e aos assemblies de runtime gerados pelo C#/WinRT.

O pacote NuGet do C#/WinRT permite criar e referenciar assemblies próprios de interoperabilidade do WinRT para consumidores do .NET. A versão mais recente do C#/WinRT também inclui uma versão prévia da criação de tipos do WinRT em C#.

Para obter informações adicionais, confira o repositório do GitHub do C#/WinRT.

Motivação para o C#/WinRT

O .NET (anteriormente conhecido como .NET Core) é um runtime entre plataformas de código aberto que pode ser usado para criar aplicativos de dispositivo, nuvem e IoT.

As versões anteriores do .NET Framework e do .NET Core tinham conhecimento interno do WinRT, uma tecnologia específica do Windows. Para dar suporte à portabilidade e à eficiência do .NET 6+, retiramos o suporte de projeção ao WinRT do compilador e do runtime do .NET e o movemos para o kit de ferramentas do C#/WinRT (veja Suporte integrado para WinRT é removido do .NET). A meta do C#/WinRT é fornecer paridade com o suporte do WinRT interno fornecido por versões anteriores do compilador do C# e do runtime do .NET. Para obter detalhes, confira Mapeamentos do .NET dos tipos do Windows Runtime.

O C#/WinRT também dá suporte a componentes no SDK do aplicativo Windows, incluindo o WinUI 3. O SDK do aplicativo Windows retira os controles nativos da interface do usuário da Microsoft e outros componentes nativos do sistema operacional. Isso permite que os desenvolvedores de aplicativos usem os controles e componentes mais recentes no Windows 10, versão 1809 e versões posteriores.

Por fim, o C#/WinRT é um kit de ferramentas geral e destina-se a dar suporte a outros cenários em que o suporte interno para o WinRT não está disponível no compilador do C# ou no runtime do .NET.

Novidades

As versões mais recentes do C#/WinRT podem ser encontradas em nossa página de notas sobre a versão no repositório Github.

Uso

O pacote de NuGet do C#/WinRT pode ser usado para gerar projeções de C# (também chamadas de assemblies de interoperabilidade) de componentes WinRT e para Criar componentes do C#/WinRT. Para obter mais detalhes sobre os cenários de uso do C#/WinRT, veja o guia de uso em nosso repositório.

Gerar e distribuir um assembly de interoperabilidade

As APIs do WinRT são definidas nos arquivos WinMD (Metadados do Windows). O pacote NuGet do C#/WinRT (Microsoft.Windows.CsWinRT) inclui um compilador do C#/WinRT, cswinrt.exe, que pode ser usado para processar arquivos de WinMD e gerar um código em C# do .NET. O C#/WinRT compila esses arquivos de origem em um assembly de interoperabilidade, semelhante à forma como o C++/WinRT gera cabeçalhos para a projeção da linguagem C++. Em seguida, você pode distribuir o assembly de interoperabilidade do C#/WinRT juntamente com o assembly de implementação para aplicativos .NET para referência, normalmente como um pacote NuGet.

Para obter mais detalhes sobre como gerar e distribuir um assembly de interoperabilidade, confira Gerar uma projeção em C# de um componente do C++/WinRT e distribui-la como um pacote NuGet para aplicativos .NET.

Fazer referência a um assembly de interoperabilidade

Normalmente, os assemblies de interoperabilidade do C#/WinRT são referenciados por projetos de aplicativo. Contudo, eles também podem ser referenciados, por sua vez, por assemblies de interoperabilidade intermediários. Por exemplo, o assembly de interoperabilidade do WinUI faria referência ao assembly de interoperabilidade do SDK do Windows.

Se você distribuir um componente do WinRT de terceiros sem um assembly de interoperabilidade oficial, um projeto de aplicativo poderá seguir o procedimento para gerar um assembly de interoperabilidade a fim de gerar as próprias fontes de projeção privadas. Não recomendamos essa abordagem, porque ela pode produzir projeções conflitantes do mesmo tipo dentro de um processo. O empacotamento do NuGet, que segue o esquema de Controle de Versão Semântica, foi criado para evitar isso. Um assembly de interoperabilidade oficial de terceiros é preferencial.

Suporte inserido para tipos de WinRT (versão prévia)

A partir do C#/WinRT versão 1.4.1, o suporte está incluído para inserir fontes de runtime e projeção do SDK do Windows para o .NET e o .NET Standard 2.0 na saída do aplicativo ou biblioteca. Isso é útil em casos em que o uso de tipos do SDK do Windows é autossuficiente. O suporte inserido remove dependências no WinRT.Runtime.dll e no Microsoft.Windows.SDK.NET.dll, o que reduz o tamanho de saída da biblioteca ou do aplicativo. Ele também permite que os desenvolvedores de biblioteca forneçam suporte de versão anterior e elimina a necessidade de vários destinos.

Para obter mais detalhes, confira a documentação do C#/WinRT incorporado em nosso repositório.

Ativação do tipo do WinRT

O C#/WinRT dá suporte à ativação de tipos do WinRT hospedados pelo sistema operacional, assim como componentes de terceiros, como Win2D. O suporte para a ativação de componentes de terceiros em um aplicativo da área de trabalho é habilitado com a ativação do WinRT sem registro (confira Como aprimorar aplicativos da área de trabalho não empacotados usando componentes do Windows Runtime), disponível no Windows 10, versão 1903 e posterior. Os componentes nativos do C++ devem definir a propriedade Compatível com Windows Desktop como True por meio das propriedades do projeto ou do arquivo .vcxproj, a fim de fazer referência e encaminhar os binários Microsoft.VCLibs.Desktop para consumo de aplicativos. Caso contrário, o pacote Encaminhadores do VCRT será exigido pelo consumo de aplicativos se o componente direcionar somente aplicativos UWP.

O C#/WinRT também fornecerá um caminho de fallback de ativação se o Windows não conseguir ativar o tipo, conforme descrito acima. Nesse caso, o C#/WinRT tenta localizar uma DLL de implementação nativa com base no nome do tipo totalmente qualificado, removendo progressivamente os elementos. Por exemplo, a lógica de fallback tentaria ativar o tipo Contoso.Controls.Widget dos seguintes módulos, em sequência:

  1. Contoso.Controls.Widget.dll
  2. Contoso.Controls.dll
  3. Contoso.dll

O C#/WinRT usa a ordem de pesquisa alternativa LoadLibrary para localizar uma DLL de implementação. Um aplicativo que dependa desse comportamento de fallback deverá empacotar a DLL de implementação juntamente com o módulo do aplicativo.

Erros comuns e solução de problemas

  • Erro: "Metadados do Windows não foram fornecidos nem detectados".

    Você pode especificar os metadados do Windows usando a propriedade do projeto <CsWinRTWindowsMetadata>, por exemplo:

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    No C#/WinRT versão 1.2.1 e posterior, essa propriedade usa como padrão TargetPlatformVersion, derivada da versão do SDK do Windows especificada na propriedade TargetFramework.

  • Erro CS0246: O tipo ou o nome do namespace 'Windows' não foi encontrado (uma diretiva de uso ou uma referência de assembly está ausente?)

    Para resolver esse erro, edite sua propriedade <TargetFramework> para ter como destino uma versão específica do Windows, por exemplo:

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    Consulte os documentos em Chamada de APIs do Windows Runtime para obter mais detalhes sobre como especificar a propriedade <TargetFramework>.

  • System.InvalidCastException ao converter para uma interface que tem o atributo ComImport

    Ao converter um objeto para uma interface que tem o atributo ComImport, você precisará usar o operador .As<> em vez de usar uma expressão de conversão explícita. Por exemplo:

    someObject.As<SomeComImportInterface>
    

    Para obter mais detalhes, confira o Guia de interoperabilidade COM.

  • System.Runtime.InteropServices.COMException: a classe não é registrada (0x80040154 (REGDB_E_CLASSNOTREG))

    • Se você vir essa exceção ao consumir uma projeção do C#/WinRT em um componente C++/WinRT, verifique se o componente definiu a propriedade Compatível com o Windows Desktop como True por meio das propriedades do projeto ou do arquivo .vcxproj.

Erros de versão do SDK do .NET

Você pode encontrar os erros ou avisos a seguir em um projeto criado com uma versão do SDK do .NET mais antiga do que qualquer uma das dependências dela.

Mensagem de erro ou de aviso Motivo
Aviso MSB3277: Foram encontrados conflitos entre diferentes versões do WinRT.Runtime ou do Microsoft.Windows.SDK.NET que não puderam ser resolvidos. Esse aviso de build ocorre quando uma biblioteca que expõe tipos de SDK do Windows na superfície de API é referenciada.
Erro CS1705: o assembly 'AssemblyName1' usa 'TypeName', que tem uma versão superior à do assembly referenciado 'AssemblyName2' Esse erro do compilador de build ocorre quando tipos de SDK do Windows expostos em uma biblioteca são referenciados e consumidos.
System.IO.FileLoadException Esse erro de runtime pode ocorrer quando certas APIs são chamadas em uma biblioteca que não expõe os tipos de SDK do Windows.

Para consertar esses erros, atualize seu SDK do .NET para a versão mais recente. Isso garantirá que as versões de assembly de runtime e do SDK do Windows usadas pelo aplicativo sejam compatíveis com todas as dependências. Esses erros podem ocorrer com atualizações antecipadas de recursos/serviços para o SDK do .NET, pois os consertos de runtime podem exigir atualizações para nossas versões do assembly.

Problemas conhecidos

Problemas conhecidos e alterações da falha são anotados no repositório do GitHub do C#/WinRT.

Se você encontrar problemas funcionais com o pacote do NuGet do C#/WinRT, o compilador cswinrt.exe ou as fontes de projeção geradas, envie os problemas para nós por meio da página de problemas do C#/WinRT.

Recursos adicionais