visual studio sistema referencias referencia puede net las guardan especificada encuentra encontrar donde c# .net vb6 com-interop

c# - studio - ¿Pasar objeto VB6 al objeto.NET a través de interoperabilidad?



el sistema no puede encontrar la referencia especificada vb net (2)

Tengo una aplicación VB6 que muestra un formulario .NET DLL a través de interoperabilidad.

Me gustaría que un evento en la DLL .NET haga que se muestre un formulario en la aplicación VB6.

Mi idea es hacer que la aplicación VB6 pase una referencia a un formulario a .NET DLL. P.ej:

[VB6] Dim objNetDllObject As New NetDllObject objNetDllObject.PassVb6Form(MyForm) objNetDllObject.ShowForm [C#] object Vb6Form; private void PassVb6Form(object form) { Vb6Form = form; } private void button1_Click(object sender, EventArgs e) { Vb6Form.Show(); }

esto funcionara?

He leído en otra parte que enviar objetos a través de un ''límite de proceso'' puede causar problemas. ¿Es esto correcto?


Una ruta sería definir una interfaz COM en .NET:

<System.Runtime.InteropServices.GuidAttribute("0896D946-8A8B-4E7D-9D0D-BB29A52B5D08"), _ InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _ Public Interface IEventHandler Sub OnEvent(ByRef sender As Object, ByRef e As Object) End Interface

Implementar esta interfaz en VB6

Implements MyInterop.IEventHandler Private Sub IEventHandler_OnEvent(ByRef sender As Variant, ByRef e As Variant) Dim id id = e.Entity.Id '' As long as e is COM Visible (not necessarily COM registered, this will work) End Sub

y luego tener un registrador en .NET con una colección estática de IEventHandlers:

<ComClass(ComRegistrar.ClassId, ComRegistrar.InterfaceId, ComRegistrar.EventsId> Public Class ComRegistrar Private Shared ReadOnly _eventHandlers As New Dictionary(Of String, List(Of IEventHandler)) '' This is called by .NET code to fire events to VB6 Public Shared Sub FireEvent(ByVal eventName As String, ByVal sender As Object, ByVal e As Object) For Each eventHandler In _eventHandlers(eventName) eventHandler.OnEvent(sender, e) Next End Sub Public Sub RegisterHandler(ByVal eventName As String, ByVal handler As IEventHandler) Dim handlers as List(Of IEventHandler) If Not _eventHandlers.TryGetValue(eventName, handlers) handlers = New List(Of IEventHandler) _eventHandlers(eventName) = handlers End If handlers.Add(handler) End Sub End Class

Su código .NET llamaría a FireEvent y si VB6 había llamado previamente a RegisterHandler, se invocaría su IEventHandler de VB6.


También podría usar ComSourceInterfacesAttribute que podría hacer que su código sea un poco más simple (o al menos más natural desde el lado VB6). Tendría un código como el siguiente:

Biblioteca C #:

namespace WindowsFormsControlLibrary1 { using System; using System.Runtime.InteropServices; using System.Windows.Forms; [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IMyFormEvents { [DispId(1)] void MyEvent(); } public delegate void MyEventEventHandler(); [ComSourceInterfaces(typeof(IMyFormEvents))] public partial class MyForm : Form { public event MyEventEventHandler MyEvent; public MyForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (this.MyEvent != null) { this.MyEvent(); } } } }

Y el cliente VB6:

Option Explicit Private WithEvents f As WindowsFormsControlLibrary1.MyForm Private Sub Command1_Click() Set f = New WindowsFormsControlLibrary1.MyForm Call f.Show End Sub Private Sub f_MyEvent() MsgBox "Event was raised from .NET" ''Open another VB6 form or do whatever is needed End Sub

Si va a utilizar una gran cantidad de .NET UI desde su aplicación VB6, le recomiendo el Interop Forms Toolkit como una forma de simplificar las cosas. (Ayuda a generar código como estas muestras, así como a manejar algunos otros escenarios comunes).