Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
À 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 ont été décorés comme visibles par COM Interop, et ont donc été accessibles au code natif. À compter de .NET 5, aucune API Windows Forms n’est visible pour l’interopérabilité COM 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 (qui nécessiterait la maintenance de la forme des classes comme elles étaient dans .NET Framework).
Raison de la modification
- Suppression de l’attribut
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 bibliothèque de types WinForms fournie par .NET Core, la conservation de cet attribut n’a aucune valeur. - Suppression de
ComVisible(true)des classesAccessibleObject: les classes ne peuvent pas être créées par CoCreate (elles n'ont pas de constructeur sans paramètre), et exposer une instance déjà existante à COM ne nécessite pas cet attribut. - Suppression de
ComVisible(true)des classesControletComponent: cela a été utilisé pour autoriser l’hébergement de contrôles WinForms via OLE/ActiveX, par exemple dans VB6 ou MFC. Toutefois, cela nécessite un TLB pour WinForms, qui n'est plus fourni, ainsi qu'une activation basée sur le registre, qui ne fonctionnerait pas automatiquement. 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
ClassInterfacedes contrôles : si l’hébergement via OLE/ActiveX n’est pas pris en charge, ces attributs ne sont plus nécessaires. Elles sont conservées 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 CoCreateable non plus, donc l’attribut n’a aucun but. En outre, l’exposition d’instances existantes sans fournir un 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)dans certains codes non publics : 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 concepteurs publics arbitraires : l’ancien concepteur de Visual Studio a peut-être utilisé l’interopérabilité COM pour interagir avec ces classes. Toutefois, l’ancien concepteur ne prend pas en charge .NET Core, donc peu de personnes en auraient besoin en tant queComVisible. IWin32Windowa défini le même GUID qui a été défini dans .NET Framework, qui a des conséquences dangereuses. Si vous avez besoin d’interopérabilité avec .NET Framework, utilisezComImport.- Le
IDataObjectWinForms managé a été renduComVisible. Cela n’est pas obligatoire, il existe une déclaration d’interface distincteComImportpourIDataObjectl’interopérabilité COM. Il est contre-productif que leIDataObjectmanagé soitComVisible, car aucun TLB n’est fourni et le marshalling échouera toujours. En outre, le GUID n’a pas été spécifié et diffère 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): celles-ci sont placées dans des emplacements apparemment arbitraires et sont redondantes 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 :
Introduire un objet
ObjectForScriptingdéclaré par l'utilisateur qui supporteIDispatch(appliqué par défaut, à moins qu'il soit 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.