Вот действительно простой .net < -> COM-пример взаимодействия с использованием событий.События, возникшие в .net-коде, не отображаются в COM-коде при развертывании с помощью боковых манифестах
Этот пример работает просто отлично, если я либо использую regasm, либо регистр для com interop вариант в Visual Studio для построения библиотеки .net. Но мне нужно разворачивать с помощью бесплатных бесплатных демонстраций регистрации без участия сторон.
Приложение работает очень хорошо в бок о бок режиме, это просто, что события, кажется, исчезает. Я подозреваю, что это проблема с сортировкой потоков, но я не могу найти правильное решение.
Это, конечно, попытка повторить проблему, имеющую несколько более сложную интеграцию интеграции. Существует одна разница между проблемами, которые возникают у меня здесь, по сравнению с реальными проблемами:
Оба решения не могут должным образом перегрузить события, создаваемые в .net-коде при работе в режиме бесплатного развертывания, и оба решения работают так, как ожидается, когда DLL .net зарегистрированы в реестре. Однако: в «реальном» проекте я получаю ошибку времени выполнения, когда она не работает с System.Reflection.Target. На этом упрощенном примере он просто терпит неудачу.
Я полностью придерживаюсь этого, поэтому любые предложения и решения будут очень приветствоваться.
Я поставил полный код на GitHub, если кому-то нужен, чтобы играть с ним, прежде чем ответить: https://github.com/Vidarls/InteropEventTest
В .NET часть
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace InteropEventTest
{
[Guid("E1BC643E-0CCF-4A91-8499-71BC48CAC01D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComVisible(true)]
public interface ITheEvents
{
void OnHappened(string theMessage);
}
[Guid("77F1EEBA-A952-4995-9384-7228F6182C32")]
[ComVisible(true)]
public interface IInteropConnection
{
void DoEvent(string theMessage);
}
[Guid("2EE25BBD-1849-4CA8-8369-D65BF47886A5")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(ITheEvents))]
[ComVisible(true)]
public class InteropConnection : IInteropConnection
{
[ComVisible(false)]
public delegate void Happened(string theMessage);
public event Happened OnHappened;
public void DoEvent(string theMessage)
{
if (OnHappened != null)
{
Task.Factory.StartNew(() => OnHappened(theMessage));
}
}
}
}
СОМ (VB6) часть
Private WithEvents tester As InteropEventTest.InteropConnection
Private Sub Command1_Click()
Call tester.DoEvent(Text1.Text)
End Sub
Private Sub Form_Load()
Set tester = New InteropConnection
End Sub
Private Sub tester_OnHappened(ByVal theMessage As String)
Text2.Text = theMessage
End Sub
В настоящее время у меня есть следующие файлы/структура папок для г развертывания:
Root
|-> [D] Interop.Event.Tester
|-> Interop.Event.Tester.manifest
|-> [D] InteropEventTest
|-> InteropEventTest.dll
|-> InteropEventTest.manifest
|-> InteropEventTest.tlb
|-> tester.exe
|-> tester.exe.manifest
Содержание файлов манифеста:
Interop.Event.Test.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="Interop.Event.Tester" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
</assembly>
InteropEventTest.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="InteropEventTest" version="1.0.0.0" type="win32"/>
<clrClass
name="InteropEventTest.InteropConnection"
clsid="{2EE25BBD-1849-4CA8-8369-D65BF47886A5}"
progid="InteropEventTest.InteropConnection"
runtimeVersion="v4.0.30319"
threadingModel="Both"/>
<file name="InteropEventTest.tlb">
<typelib
tlbid="{5CD6C635-503F-4103-93B0-3EBEFB91E500}"
version="1.0"
helpdir=""
flags="hasdiskimage"/>
</file>
<comInterfaceExternalProxyStub
name="ITheEvents"
iid="{E1BC643E-0CCF-4A91-8499-71BC48CAC01D}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{5CD6C635-503F-4103-93B0-3EBEFB91E500}" />
</assembly>
тэ ster.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="tester.exe" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
<dependency>
<dependentAssembly>
<assemblyIdentity name="InteropEventTest" version="1.0.0.0" type="win32"/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity name="Interop.Event.Tester" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
</dependentAssembly>
</dependency>
</assembly>
Компиляция, как P-код [официальный Microsoft обходной] (http://stackoverflow.com/questions/2785169/using-the-net-backgroundworker-from -vb6-fail-with-an-accessviolationexception) к некоторым ошибкам COM-взаимодействия. Конечно, возможно, что вы испытываете совершенно несвязанный вопрос. – MarkJ