ISearchManager2 проблема с подписью C # - PullRequest
1 голос
/ 13 марта 2019

Я пытаюсь загрузить ISearchManager2 интерфейс на C #.

До этого момента все отлично работало с ISearchManager. Для этого я использовал сборку Microsoft.Search.Interop. Я могу установить каталоги, получить некоторые результаты от индексатора и другие вещи.

НО, теперь я хочу интерфейс с именем ISearchManager2, поэтому я создал:

[ComConversionLoss]
[ComImport]
[Guid("DBAB3F73-DB19-4A79-BFC0-A61A93886DDF")]
[InterfaceType(1)]
public interface ISearchManager2 : ISearchManager
{
    void CreateCatalog([MarshalAs(UnmanagedType.LPWStr)] [In] string pszCatalog, out ISearchCatalogManager _out);
    void DeleteCatalog([MarshalAs(UnmanagedType.LPWStr)] string pszCatalog);
}

Та же подпись и порядок от searchapi.h, что:

MIDL_INTERFACE("DBAB3F73-DB19-4A79-BFC0-A61A93886DDF")
ISearchManager2 : public ISearchManager
{
public:
    virtual HRESULT STDMETHODCALLTYPE CreateCatalog( 
        /* [string][in] */ __RPC__in_string LPCWSTR pszCatalog,
        /* [out] */ __RPC__deref_out_opt ISearchCatalogManager **ppCatalogManager) = 0;

    virtual HRESULT STDMETHODCALLTYPE DeleteCatalog( 
        /* [string][in] */ __RPC__in_string LPCWSTR pszCatalog) = 0;
};

С действительным ISearchManager Я кастую как:

ISearchCatalogManager _out;
Teste _test = (Teste)_searchManager;
_test.CreateCatalog(catalog, out _out);

Нет ошибки с QueryInterface (это означает, что интерфейс был найден) и нет исключений (с ошибками). НО, это никогда не назначается. Отладка этого, я вижу, что string catalog меняется.

[1]

Это до звонка CreateCatalog. И после:

[2]

Я предполагаю, что C # вызывается с дополнительным аргументом, а второе (значение out) это строка. Я пробовал с PreserveSigAttribute и другими вещами, такими как:

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CreateCatalog([MarshalAs(UnmanagedType.LPWStr)] [In] string pszCatalog, out ISearchCatalogManager _out);

Потому что, когда я декомпилирую интерфейс из ISearchManager (из Microsoft.Search.Interop), я вижу этот атрибут в функции GetCatalog с такой же сигнатурой.

У кого-то есть идеи, почему это происходит?

1 Ответ

1 голос
/ 13 марта 2019

При объявлении унаследованных интерфейсов COM в .NET вы должны объявить все члены унаследованных интерфейсов рекурсивно.Так, например, если у вас есть это в качестве базового интерфейса:

[Guid("2cd90691-12e2-11dc-9fed-001143a055f9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IBase
{
    int Blabla();
}

Тогда определение IDerived будет выглядеть примерно так:

[Guid("65019f75-8da2-497c-b32c-dfa34e48ede6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerived
{
    // IBase methods
    int Blabla();

    // IDerived methods
    ...
}

Или лучше, как это, есливы хотите сохранить иерархию наследования в .NET:

[Guid("65019f75-8da2-497c-b32c-dfa34e48ede6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerived : IBase
{
    // IBase methods
    new int Blabla();

    // IDerived methods
    ...
}
...