Sdílet prostřednictvím


Nativní kód nemá přístup k objektům model Windows Forms

Počínaje rozhraním .NET 5 už nemáte přístup k objektům model Windows Forms z nativního kódu.

Změna popisu

V předchozích verzích rozhraní .NET byly některé typy model Windows Forms vyzdobeny jako viditelné pro zprostředkovatele komunikace s objekty COM, a proto byly přístupné nativnímu kódu. Počínaje rozhraním .NET 5 nejsou pro zprostředkovatele komunikace modelu COM viditelné žádné model Windows Forms rozhraní API nebo přístupné nativnímu kódu. Modul runtime .NET už nepodporuje vytváření vlastních knihoven typů. Modul runtime .NET navíc nemůže záviset na knihovně typů pro rozhraní .NET Framework (což by vyžadovalo zachování tvaru tříd v rozhraní .NET Framework).

Důvod změny

  • ComVisible(true) Odebrání z výčtů, které byly použity pro generování knihovny typů (soubor TLB) a vyhledávání: Vzhledem k tomu, že rozhraní .NET Core neposkytuje žádné nástroje WinForms TLB, není v tomto atributu žádná hodnota.
  • ComVisible(true) Odebrání z AccessibleObject tříd: Třídy nejsou CoCreateable (nemají žádný konstruktor bez parametrů) a zveřejnění již existující instance modelu COM nevyžaduje tento atribut.
  • Odebrání z Control a Component tříd: To bylo použito k povolení hostování ovládacích ComVisible(true) prvků WinForms prostřednictvím OLE/technologie ActiveX, například v VB6 nebo MFC. To ale vyžaduje TLB pro WinForms, který už není k dispozici, ani aktivaci na základě registru, která by také nefungovala. Obecně neproběhla žádná údržba hostování ovládacích prvků WinForms založených na modelu COM, takže podpora byla odebrána místo toho, aby byla ponechána v nepodporovaném stavu.
  • Odebrání atributů z ovládacích ClassInterface prvků: Pokud není podporováno hostování přes OLE/technologie ActiveX, tyto atributy už nejsou potřeba. Jsou uloženy na jiných místech, kde jsou objekty stále vystaveny modelu COM a atribut může být relevantní.
  • Odebrání z ComVisible(true) EventArgs: Byly pravděpodobně použity s OLE/technologie ActiveX hosting, který již není podporován. Nejsou ani CoCreateable, takže atribut nemá žádný účel. Zveřejnění existujících instancí bez poskytnutí nástroje pro vyrovnávání zatížení nemá smysl.
  • ComVisible(true) Odebrání delegátů: Účel je neznámý, ale protože technologie ActiveX hostování ovládacích prvků WinForms už není podporováno, je nepravděpodobné, že by to mělo nějakou užitečnost.
  • Odebrání z některého ComVisible(true) neveřejného kódu: Jediným potenciálním uživatelem by byl nový návrhář sady Visual Studio, ale bez zadaného identifikátoru GUID není pravděpodobné, že by byl stále potřeba.
  • Odebrání z některých libovolných ComVisible(true) veřejných tříd návrháře: Starý návrhář sady Visual Studio mohl používat zprostředkovatele komunikace modelu COM ke komunikaci s těmito třídami. Starý návrhář ale nepodporuje .NET Core, takže by je potřebovalo jen málo lidí.ComVisible
  • IWin32Window definoval stejný identifikátor GUID, který byl definován v rozhraní .NET Framework, což má nebezpečné důsledky. Pokud potřebujete interoperabilitu s rozhraním .NET Framework, použijte ComImport.
  • Byl proveden ComVisiblepříkaz IDataObject WinForms . To není povinné, existuje samostatná ComImport deklarace rozhraní pro IDataObject interoperabilitu COM. Je to kontraproduktivní mít spravované IDataObject ComVisible, protože není k dispozici žádný TLB a zařazování vždy selže. Také identifikátor GUID nebyl zadán a liší se od rozhraní .NET Framework, takže jeho nepravděpodobné, že odebrání nezdokumentovaného IDENTIFIKÁTORu IID ovlivní zákazníky negativně.
  • ComVisible(false)Odebrání : Ty jsou umístěny do zdánlivě libovolných míst a jsou redundantní, pokud výchozí hodnota není vystavit třídy pro interoperabilitu COM.

Zavedená verze

.NET 5.0

Následující příklad funguje v rozhraní .NET Framework a .NET Core 3.1. Tento příklad spoléhá na knihovnu typů rozhraní .NET Framework, která umožňuje javascriptu volat zpět do podtřídy formuláře prostřednictvím reflexe.

[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");
    }
}

Příklad funguje na platformě .NET 5 a novějších verzích dvěma způsoby:

  • Zavedení uživatelem deklarovaného ObjectForScripting objektu, který podporuje IDispatch (který se ve výchozím nastavení používá, pokud se nezmění explicitně na úrovni projektu).

    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);
    
            ...
        }
    }
    
  • Deklarujte rozhraní s metodami, které se mají zveřejnit.

    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;
    
            ...
        }
    }
    

Ovlivněná rozhraní API

Všechna rozhraní API model Windows Forms.