Le code natif ne peut pas accéder aux objets Windows Forms
À compter de .NET 5, vous ne pouvez plus accéder aux objets Windows Forms à partir du code natif.
Description de la modification
Dans les versions précédentes de .NET, certains types Windows Forms étaient décorés comme étant visibles par COM Interop, et étaient donc accessibles au code natif. À compter de .NET 5, aucune API Windows Forms n’est visible pour COM Interop ou accessible au code natif. Le runtime .NET ne prend plus en charge la création de bibliothèques de types personnalisées prêtes à l’emploi. En outre, le runtime .NET ne peut pas dépendre de la bibliothèque de types pour .NET Framework (ce qui nécessiterait la maintenance de la forme des classes comme elles étaient dans .NET Framework).
Raison du changement
- Suppression de
ComVisible(true)
des énumérations utilisées pour la génération et la recherche de bibliothèque de types (fichier TLB) : étant donné qu’il n’existe pas de fichiers TLB WinForms fournis par .NET Core, conserver cet attribut n’a pas d’intérêt. - Suppression de
ComVisible(true)
de classesAccessibleObject
: les classes ne sont pas cocréables (elles n’ont aucun constructeur sans paramètre) et l’exposition d’une instance déjà existante à COM ne nécessite pas cet attribut. - Suppression de
ComVisible(true)
des classesControl
etComponent
: cette option était utilisée pour autoriser l’hébergement de contrôles WinForms via OLE/ActiveX, par exemple dans VB6 ou MFC. Toutefois, cela nécessite un fichier TLB pour WinForms, qui n’est plus fourni, ainsi que l’activation basée sur le Registre, qui ne fonctionnerait pas non plus telle quelle. En règle générale, il n’y a pas eu de maintenance de l’hébergement COM des contrôles WinForms. La prise en charge a donc été supprimée au lieu de la laisser dans un état non pris en charge. - Suppression des attributs
ClassInterface
des contrôles : si l’hébergement via OLE/ActiveX n’est pas pris en charge, ces attributs ne sont plus nécessaires. Ils sont conservés dans d’autres endroits où les objets sont toujours exposés à COM et l’attribut peut être pertinent. - Suppression de
ComVisible(true)
deEventArgs
: ils étaient probablement utilisés avec l’hébergement OLE/ActiveX, qui n’est plus pris en charge. Ils ne sont pas cocréables non plus, de sorte que l’attribut n’a aucun but. En outre, l’exposition d’instances existantes sans fournir de fichier TLB n’a aucun sens. - Suppression de
ComVisible(true)
des délégués : l’objectif est inconnu, mais étant donné que l’hébergement ActiveX des contrôles WinForms n’est plus pris en charge, il est peu probable qu’il ait une utilité. - Suppression de
ComVisible(true)
d’un code non public : le seul consommateur potentiel serait le nouveau concepteur Visual Studio, mais sans GUID spécifié, il est peu probable qu’il soit toujours nécessaire. - Suppression de
ComVisible(true)
de certaines classes de concepteur public arbitraires : l’ancien concepteur Visual Studio a peut-être utilisé COM Interop pour communiquer avec ces classes. Toutefois, l’ancien concepteur ne prend pas en charge .NET Core, donc peu de personnes en auraient besoin en tant queComVisible
. IWin32Window
définissait le même GUID que celui qui était défini dans .NET Framework, ce qui a des conséquences dangereuses. Si vous avez besoin d’interopérabilité avec .NET Framework, utilisezComImport
.- Le
IDataObject
WinForms managé a été renduComVisible
. Cela n’est pas obligatoire, il existe une déclaration d’interfaceComImport
distincte pourIDataObject
COM Interop. Il est contre-productif que leIDataObject
managé soitComVisible
, car aucun TLB n’est fourni et le marshalling échouera toujours. En outre, le GUID n’était pas spécifié et différait de .NET Framework. Par conséquent, il est peu probable que la suppression d’un IID non documenté affecte négativement les clients. - Suppression de
ComVisible(false)
: ces éléments sont placés dans des endroits apparemment arbitraires et sont redondants lorsque la valeur par défaut consiste à ne pas exposer les classes à COM Interop.
Version introduite
.NET 5.0
Action recommandée
L’exemple suivant fonctionne sur .NET Framework et .NET Core 3.1. Cet exemple s’appuie sur la bibliothèque de types .NET Framework, qui permet au JavaScript d’effectuer un rappel dans la sous-classe de formulaire via la réflexion.
[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");
}
}
Il existe deux façons de faire en sorte que l’exemple fonctionne sur .NET 5 et les versions ultérieures :
Introduisez un objet
ObjectForScripting
déclaré par l’utilisateur qui prend en chargeIDispatch
(appliqué par défaut, sauf si modifié explicitement au niveau du projet).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); ... } }
Déclarez une interface avec les méthodes à exposer.
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; ... } }
API affectées
Toutes les API Windows Forms.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour