Partilhar via


C#/WinRT

C#/WinRT é um kit de ferramentas incluído no NuGet que fornece suporte para projeção do Windows Runtime (WinRT) para a linguagem C#. Um assembly de projeção é um assembly de interoperabilidade, que permite programar APIs WinRT de forma natural e familiar para a linguagem alvo. A projeção C#/WinRT oculta os detalhes da interoperabilidade entre as interfaces C# e WinRT e fornece mapeamentos de muitos tipos WinRT para equivalentes adequados do .NET, como strings, URIs, tipos de valores comuns e coleções genéricas.

Atualmente, o C#/WinRT oferece suporte para o consumo de APIs WinRT através da utilização de Target Framework Monikers (TFMs) em .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 execução gerados por C#/WinRT.

O pacote NuGet C#/WinRT permite-lhe criar e referenciar os seus próprios assemblies de interoperabilidade WinRT para consumidores .NET. A versão mais recente de C#/WinRT inclui também uma pré-visualização da autoria dos tipos WinRT em C#.

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

Motivação para C#/WinRT

.NET (anteriormente conhecido como .NET Core) é um runtime open-source e multiplataforma que pode ser usado para construir aplicações de dispositivos, cloud e IoT.

Versões anteriores do .NET Framework e do .NET Core tinham conhecimento incorporado do WinRT — uma tecnologia específica do Windows. Para apoiar os objetivos de portabilidade e eficiência do .NET 6+, retirámos o suporte de projeção WinRT do compilador e runtime de .NET e transferimo-lo para o toolkit C#/WinRT (ver O suporte incorporado para WinRT foi removido do .NET). O objetivo do C#/WinRT é proporcionar paridade com o suporte WinRT incorporado fornecido pelas versões anteriores do compilador C# e do runtime .NET. Para mais detalhes, consulte mapeamentos de tipos do Windows Runtime no .NET.

C#/WinRT também suporta componentes no Windows App SDK, incluindo o WinUI 3. O Windows App SDK retira os controlos nativos da interface Microsoft e outros componentes nativos do sistema operativo. Isto permite aos programadores de aplicações utilizar os controlos e componentes mais recentes no Windows 10, versão 1809 e versões posteriores.

Finalmente, C#/WinRT é um conjunto de ferramentas geral e destina-se a suportar outros cenários onde o suporte incorporado para WinRT não está disponível no compilador C# ou no runtime .NET.

O que há de novo

Os lançamentos mais recentes de C#/WinRT podem ser encontrados na nossa página de notas de lançamento no repositório Github.

Usage

O pacote NuGet C#/WinRT pode ser usado tanto para gerar projeções C# (também chamadas de conjuntos interop) a partir de componentes WinRT como em componentes Authoring C#/WinRT. Para mais detalhes sobre os cenários de utilização de C#/WinRT, consulte o guia uso no nosso repositório.

Gerar e distribuir um conjunto de interoperabilidade

As APIs WinRT são definidas em ficheiros de Metadados do Windows (WinMD). O pacote NuGet C#/WinRT (Microsoft.Windows.CsWinRT) inclui o compilador C#/WinRT cswinrt.exe, que pode usar para processar ficheiros WinMD e gerar .NET código C#. O C#/WinRT compila estes ficheiros fonte numa assembly interop, semelhante à forma como o C++/WinRT gera cabeçalhos para a projeção da linguagem C++. Pode então distribuir o assembly de interoperabilidade C#/WinRT juntamente com o assembly de implementação para que aplicações .NET possam referenciar, normalmente como um pacote NuGet.

Para mais detalhes sobre como gerar e distribuir um assembly interop, veja Gere uma projeção C# a partir de um componente C++/WinRT, distribuir como um NuGet para .NET aplicações.

Referência a um conjunto de interoperabilidade

Normalmente, os assemblies de interoperação C#/WinRT são referenciados por projetos de aplicativos. Mas também podem ser referenciados por conjuntos interoperativos intermédios. Por exemplo, o assembly de interoperabilidade do WinUI faria referência ao assembly de interoperabilidade do SDK do Windows.

Se distribuir um componente WinRT de terceiros sem um assembly oficial de interoperabilidade, uma aplicação projeto pode seguir o procedimento para gerar um assembly de interoperabilidade para gerar as suas próprias fontes privadas de projeção. Não recomendamos esta abordagem, pois pode produzir projeções conflitantes do mesmo tipo dentro de um processo. O empacotamento NuGet, seguindo o esquema de Semantic Versioning, é projetado para prevenir isto. Prefere-se uma assembleia oficial de interoperabilidade de terceiros.

Suporte embutido para tipos WinRT (Pré-visualização)

A partir da versão 1.4.1 do C#/WinRT, está incluído suporte para incorporar projeções e fontes de tempo de execução do SDK do Windows tanto para .NET como para .NET Standard 2.0 na saída da sua biblioteca ou aplicação. Isto é útil em casos em que a utilização dos tipos de SDK do Windows é autónoma. O suporte embutido remove dependências do WinRT.Runtime.dll e do Microsoft.Windows.SDK.NET.dll o que reduz o tamanho da saída da biblioteca ou da aplicação. Também permite aos programadores de bibliotecas fornecer suporte downlevel e elimina a necessidade de multi-direcionamento.

Para mais detalhes, consulte a documentação incorporada C#/WinRT no nosso repositório.

Ativação do tipo WinRT

O C#/WinRT suporta a ativação de tipos WinRT alojados pelo sistema operativo, bem como componentes de terceiros como o Win2D. O suporte para ativação de componentes de terceiros numa aplicação de desktop está ativado com ativação WinRT sem registo (ver Melhoria de Aplicações de Desktop Não Empacotadas usando Componentes Windows Runtime), disponível em Windows 10, versão 1903 e posteriores. Os componentes nativos C++ devem definir a propriedade Windows Desktop Compatible para True através das propriedades do projeto ou do ficheiro .vcxproj, para referenciar e encaminhar os binários Microsoft.VCLibs.Desktop para as aplicações que os consomem. Caso contrário, o pacote VCRT Forwarders será necessário para aplicações que utilizam o componente se este se destinar exclusivamente a aplicações UWP.

C#/WinRT também fornece um caminho de ativação se o Windows não conseguir ativar o tipo descrito acima. Neste caso, o C#/WinRT tenta localizar uma DLL nativa de implementação baseada no nome do tipo totalmente qualificado, removendo progressivamente elementos. Por exemplo, a lógica de substituição 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

A ordem alternativa de pesquisa LoadLibrary é utilizada pelo C#/WinRT para localizar uma DLL de implementação. Uma aplicação que dependa deste comportamento alternativo deve incluir a DLL de implementação juntamente com o módulo da aplicação.

Erros comuns e solução de problemas

  • Erro: "Metadados do Windows não fornecidos ou detetados."

    Pode especificar metadados do Windows usando a propriedade <CsWinRTWindowsMetadata> project, por exemplo:

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    No C#/WinRT versão 1.2.1 e posteriores, esta propriedade é predefinida para TargetPlatformVersion, que é derivada da versão do SDK do Windows especificada na TargetFramework propriedade.

  • Erro CS0246: O nome do tipo ou namespace 'Windows' não pôde ser encontrado (falta uma diretiva de using ou uma referência de assembly?)

    Para corrigir este erro, edite a sua <TargetFramework> propriedade para direcionar uma versão específica do Windows, por exemplo:

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

    Consulte a documentação em Calling Windows Runtime APIs para mais detalhes sobre a especificação da propriedade <TargetFramework>.

  • System.InvalidCastException ao realizar um casting para uma interface que tem o atributo ComImport

    Ao converter um objeto para uma interface que possui o atributo ComImport, deverá usar o operador .As<> em vez de uma expressão de cast explícita. Por exemplo:

    someObject.As<SomeComImportInterface>
    

    Para mais detalhes, consulte o guia de interoperabilidade COM.

  • System.Runtime.InteropServices.COMException: Classe não registada (0x80040154 (REGDB_E_CLASSNOTREG))

    • Se vir esta exceção ao consumir uma projeção C#/WinRT de um componente C++/WinRT, certifique-se de que o componente definiu a propriedade Windows Desktop Compatible para True seja através das propriedades project ou do ficheiro .vcxproj.

Erros de versionamento do SDK .NET

Pode encontrar os seguintes erros ou avisos num projeto construído com uma versão .NET SDK anterior a qualquer uma das suas dependências.

Mensagem de erro ou aviso Reason
Aviso MSB3277: Encontrei conflitos entre diferentes versões do WinRT.Runtime ou Microsoft.Windows.SDK.NET que não puderam ser resolvidos. Este aviso de compilação ocorre ao referenciar uma biblioteca que expõe tipos de SDK do Windows na sua superfície da API.
Erro CS1705: Assembly 'AssemblyName1' usa 'TypeName' que tem uma versão superior à assembly referenciada 'AssemblyName2' Este erro do compilador de compilação ocorre ao referenciar e consumir tipos de SDK Windows expostos numa biblioteca.
System.IO.FileLoadException Este erro de execução pode ocorrer ao chamar certas APIs numa biblioteca que não expõe tipos de SDK do Windows.

Para corrigir estes erros, atualize o seu SDK .NET para a versão mais recente. Fazer isso garantirá que as versões de assembly em tempo de execução e do SDK do Windows usadas pela sua aplicação são compatíveis com todas as dependências. Estes erros podem ocorrer com atualizações iniciais de manutenção/funcionalidades do SDK .NET, porque as correções em tempo de execução podem exigir atualizações das nossas versões de assembly.

Problemas conhecidos

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

Se encontrar algum problema funcional com o pacote NuGet C#/WinRT, o compilador cswinrt.exe ou as fontes de projeção geradas, submeta os problemas através da página de problemas C#/WinRT.

Recursos adicionais