// MyComponent.cs
// compile csc /t:library MyComponent.cs
// post-build command: regasm MyComponent.dll /codebase
using System;
using System.Runtime.InteropServices;
using System.Timers;
using System.Windows.Forms;
namespace AddIn
{
[Guid(@"AB634001-F13D-11D0-A459-004095E1DAEA"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitDone
{
void Init([MarshalAs(UnmanagedType.IDispatch)] Object pConnection);
void Done();
void GetInfo([MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_VARIANT)] ref Object[] pInfo);
}
[Guid("AB634004-F13D-11D0-A459-004095E1DAEA"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAsyncEvent
{
void SetEventBufferDepth(Int32 depth);
void GetEventBufferDepth(ref Int32 depth);
void ExternalEvent([MarshalAs(UnmanagedType.BStr)] String source,
[MarshalAs(UnmanagedType.BStr)] String message,
[MarshalAs(UnmanagedType.BStr)] String data);
void CleanBuffer();
}
/* Component implementation */
[ComVisible(true),
ProgId(@"AddIn.MyComponent"),
Guid(@"73d61140-e6b2-47df-9d8c-6a2f788d0a53"),
ClassInterface(ClassInterfaceType.AutoDispatch)]
public class MyComponent : IInitDone
{
private static IAsyncEvent eventDispatcher;
private static Object application;
private static System.Timers.Timer eventTimer;
public MyComponent()
{
/* Constructor */
}
public void Init([MarshalAs(UnmanagedType.IDispatch)] Object pConnection)
{
try
{
application = pConnection;
eventDispatcher = (IAsyncEvent)pConnection;
/* Setup timer */
eventTimer = new System.Timers.Timer();
eventTimer.Elapsed += new ElapsedEventHandler(OnEventTimer);
eventTimer.Interval = 10000; // Every ten seconds
eventTimer.Enabled = true;
eventDispatcher.ExternalEvent("AddIn", "Type", "Usual Event");
}
catch
{
throw new COMException(@"Unknown object context");
}
}
public void Done()
{
application = null;
eventDispatcher = null;
}
public void GetInfo([MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_VARIANT)] ref Object[] pInfo)
{
pInfo[0] = @"2000"; // Required
}
private static void OnEventTimer(object source, ElapsedEventArgs e)
{
try
{
eventDispatcher.ExternalEvent("AddIn", "Type", "Thread Event");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
Вызов unmanaged-методов в COM-компоненте
Код:
Это внешняя компонента (ВК) к 1С, отсюда и наследование интерфейса IInitDone.
Отправка сообщения в 1С осуществляется с помощью метода ExternalEvent интерфейса IAsyncEvent. Из основного потока отправка осуществляется нормально, а вот при попытке отправки из потока таймера вылетает исключение:
Код:
Unable to cast COM object of type 'System.__ComObject' to interface type 'AddIn.IAsyncEvent'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{GUID}' failed due to the follow error: No such interface supported
Что-то мне подсказывает что дело в маршалинге, в том что он на другой поток не распространяется. Но что надо дописать и куда - понятия не имею. Кто имел дело с COM'ом и C# подскажите?
Код:
regasm MyComponent.dll /tlb