Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A partir do .NET 5, você não pode mais acessar objetos do Windows Forms a partir do código nativo.
Alterar descrição
Em versões anteriores do .NET, alguns tipos de Windows Forms eram decorados como visíveis para interoperabilidade COM e, portanto, eram acessíveis ao código nativo. A partir do .NET 5, nenhuma API do Windows Forms é visível para interoperabilidade COM ou acessível para código nativo. O tempo de execução do .NET não suporta mais a criação de bibliotecas de tipos personalizados prontas para uso. Além disso, o tempo de execução do .NET não pode depender da biblioteca de tipos do .NET Framework (o que exigiria manter a forma das classes como estavam no .NET Framework).
Motivo da mudança
- Remoção de
ComVisible(true)das enumerações que foram usadas para geração e pesquisa de biblioteca de tipos (arquivo TLB): Dado que não existe um WinForms TLB fornecido pelo .NET Core, não faz sentido manter este atributo. - Remoção de
ComVisible(true)das classesAccessibleObject: As classes não são CoCreateable (não têm um construtor sem parâmetros) e expor uma instância já existente para COM não requer esse atributo. - Remoção de
ComVisible(true)das classesControleComponent: Este elemento foi usado para permitir a hospedagem de controlos WinForms via OLE/ActiveX, por exemplo, em VB6 ou MFC. No entanto, isso requer um TLB para WinForms, que não é mais fornecido, bem como ativação baseada no registro, que também não funcionaria fora da caixa. Geralmente, não havia manutenção de hospedagem baseada em COM de controles WinForms, então o suporte foi removido em vez de deixá-lo em um estado sem suporte. - Remoção de
ClassInterfaceatributos de controles: Se a hospedagem via OLE/ActiveX não for suportada, esses atributos não serão mais necessários. Eles são mantidos em outros lugares onde os objetos ainda estão expostos à OCM e o atributo pode ser relevante. - Remoção de
ComVisible(true)deEventArgs: Eles foram provavelmente utilizados com hospedagem OLE / ActiveX, que já não é suportada. Eles também não são CoCreateable, então o atributo não tem propósito. Além disso, expor instâncias existentes sem fornecer um TLB não faz sentido. - Remoção de
ComVisible(true)dos delegados: O objetivo é desconhecido, mas como o suporte ao ActiveX para controles WinForms não é mais fornecido, é improvável que tenha qualquer utilidade. - Remoção do
ComVisible(true)de algum código não público: o único consumidor potencial seria o novo designer do Visual Studio, mas sem um GUID especificado, é improvável que ainda seja necessário. - Remoção de
ComVisible(true)de algumas classes arbitrárias de editor público: O editor antigo do Visual Studio poderia estar usando interoperabilidade COM para comunicar-se com estas classes. No entanto, o designer antigo não suporta .NET Core, então poucas pessoas precisariam deles comoComVisible. -
IWin32Windowusou o mesmo GUID já definido no .NET Framework, o que tem consequências perigosas. Se você precisar de interoperabilidade com o .NET Framework, useComImport. - O WinForms gerenciado
IDataObjectfoi feitoComVisible. Isso não é necessário, há uma declaração separada de interfaceComImportparaIDataObjectCOM interop. É contraproducente ter oIDataObjectgerido comoComVisible, uma vez que nenhum TLB é fornecido e o marshalling sempre falhará. Além disso, o GUID não foi especificado e diferiu do .NET Framework, portanto, é improvável que a remoção de um IID não documentado afete negativamente os clientes. - Remoção de
ComVisible(false): Estes são colocados em lugares aparentemente arbitrários e são redundantes quando o padrão é não expor classes à interoperabilidade COM.
Versão introduzida
.NET 5.0
Ação recomendada
O exemplo a seguir funciona no .NET Framework e no .NET Core 3.1. Este exemplo depende da biblioteca de tipos do .NET Framework, que permite que o JavaScript chame de volta para a subclasse do formulário por meio de reflexão.
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
private WebBrowser webBrowser1 = new WebBrowser();
protected override void OnLoad(EventArgs e)
{
webBrowser1.AllowWebBrowserDrop = false;
webBrowser1.IsWebBrowserContextMenuEnabled = false;
webBrowser1.WebBrowserShortcutsEnabled = false;
webBrowser1.ObjectForScripting = this;
webBrowser1.DocumentText =
"<html><body><button " +
"onclick=\"window.external.Test('called from script code')\">" +
"call client code from script code</button>" +
"</body></html>";
}
public void Test(String message)
{
MessageBox.Show(message, "client code");
}
}
Há duas maneiras possíveis de fazer o exemplo funcionar no .NET 5 e versões posteriores:
Introduza um objeto declarado
ObjectForScriptingpelo usuário que ofereça suporteIDispatch(que é aplicado por padrão, a menos que seja alterado explicitamente no nível do projeto).public class MyScriptObject { private Form1 _form; public MyScriptObject(Form1 form) { _form = form; } public void Test(string message) { MessageBox.Show(message, "client code"); } } public partial class Form1 : Form { protected override void OnLoad(EventArgs e) { ... // Works correctly. webBrowser1.ObjectForScripting = new MyScriptObject(this); ... } }Declare uma interface com os métodos a serem expostos.
public interface IForm1 { void Test(string message); } [ComDefaultInterface(typeof(IForm1))] public partial class Form1 : Form, IForm1 { protected override void OnLoad(EventArgs e) { ... // Works correctly. webBrowser1.ObjectForScripting = this; ... } }
APIs afetadas
Todas as APIs do Windows Forms.