У меня есть этот интерфейс в dll (этот код показан в Visual Studio из метаданных):
#region Assembly XCapture.dll, v2.0.50727
// d:\svn\dashboard\trunk\Source\MockDiagnosticsServer\lib\XCapture.dll
#endregion
using System;
using System.Runtime.InteropServices;
namespace XCapture
{
[TypeLibType(4160)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
public interface IDiagnostics
{
[DispId(1)]
void GetStatusInfo(int index, ref object data);
}
}
Итак, я создал COM-сервер с таким классом:
[ComVisible(true)]
[Guid(SimpleDiagnosticsMock.CLSID)]
[ComDefaultInterface(typeof(IDiagnostics))]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleDiagnosticsMock : ReferenceCountedObject, IDiagnostics
{
public const string CLSID = "281C897B-A81F-4C61-8472-79B61B99A6BC";
// These routines perform the additional COM registration needed by
// the service. ---- stripped from example
void IDiagnostics.GetStatusInfo(int index, ref object data)
{
Log.Info("GetStatusInfo called with index={0}, data={1}", index, data);
data = index.ToString();
}
}
Сервер работает нормально, и я могу использовать этот объект из VBScript. Но потом я пытаюсь использовать его у другого клиента С#:
[STAThread]
static void Main(string[] args)
{
Guid mockClsId = new Guid("281C897B-A81F-4C61-8472-79B61B99A6BC");
Type mockType = Type.GetTypeFromCLSID(mockClsId, true);
IDiagnostics mock = (IDiagnostics)Activator.CreateInstance(mockType);
//var diag = mock as IDiagnostics;
object s = null;
mock.GetStatusInfo(3, ref s);
Console.WriteLine(s);
Console.ReadKey();
}
И он терпит неудачу с
Невозможно передать COM-объект типа "System.__ ComObject" в интерфейс введите "XCapture.IDiagnostics". Эта операция завершилась неудачно, поскольку QueryInterface вызывает COM-компонент для интерфейса с IID '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} не удалось из-за следующих Ошибка: такой интерфейс не поддерживается (исключение из HRESULT: 0x80004002 (E_NOINTERFACE)).
Что я делаю неправильно?
Я также пытался использовать InvokeMember, и этот вид работал, за исключением того, что мне не удалось получить возвращаемый ref datastrong > .
EDIT: добавлен атрибут STAThread для моей основной процедуры. Это не решает проблему, но вы действительно должны использовать STAThread с COM, если вы не уверены, что вам это не нужно. См. Ответ Hans Passant ниже.