Передача аргумента методу COM Dispatch в Rust с помощью windows-rs

Я пытаюсь вызвать метод Move для объекта Outlook MailItem Dispatch, и мне нужно предоставить MAPIFolder в качестве аргумента.

Я могу вызывать/получать другие методы/свойства, которые не требуют никаких аргументов, но все попытки предоставить аргументы приводили к различным ошибкам.

Из их GUID я знаю, что электронная почта — это _MailItem, а папка — MAPIFolder.

Я также могу получить Dispid _MailItem.Move.

Судя по документации, Move должен принимать в качестве аргумента один MAPIFolder.

В этом примере отображается HRESULT 0x80020009, который является «исключением», и описанием является «Свойство доступно только для чтения». Я понятия не имею, о каком свойстве какого объекта идет речь.

let email : IDispatch = ...;
let folder : IDispatch = ...;

let args = vec![VARIANT::from(folder)];

let dispparams = DISPPARAMS {
    rgvarg : args.as_mut_ptr() as *mut VARIANT,
    rgdispidNamedArgs : null_mut() as *mut i32,
    cArgs : 1,
    cNamedArgs : 0,
};

let mut result = EXCEPINFO::default();
let mut exception = VARIANT::new();

unsafe {
email.Invoke(
    move_dispid, // Method ID
    &GUID::zeroed(), // reserved
    LOCALE_USER_DEFAULT, // constant, 0x0400
    0x01 | 0x08, // constant, Method | ByRef
    &dispparams as *const DISPPARAMS,
    Some(&mut result as *mut VARIANT),
    Some(&mut exception as *mut EXCEPINFO),
    None,
)
};

Каков тип варианта аргумента? Это vt_dispatch? Или vt_variant?

Dmitry Streblechenko 03.04.2024 21:20

@DmitryStrebleченко Я считаю, что ВАРИАНТ, созданный из отправки папки, должен иметь vt 9, так что vt_dispatch? Должно ли это быть vt_variant? В документах Outlook по этому поводу нет ясности.

ricky 03.04.2024 21:32

vt_dispatch должно быть хорошо. Вы уверены, что папка не пустая?

Dmitry Streblechenko 03.04.2024 22:54

@ДмитриСтреблеченко Да. Я могу получить его свойство Name и его GUID.

ricky 03.04.2024 23:25

Как вы думаете, почему Mover нужны именованные аргументы, а не обычные аргументы? У вас другая ошибка?

Dmitry Streblechenko 03.04.2024 23:35

Давайте продолжим обсуждение в чате.

ricky 04.04.2024 11:03

Я бы предпочел продолжить обсуждение здесь для пользы других разработчиков...

Dmitry Streblechenko 04.04.2024 18:07

@DmitryStreblekova Моя вина. Я думал, что чат общедоступен, и просто последовал совету SO. Я думал, что ошибка использования позиционных аргументов была «Отсутствует аргумент», но на самом деле это было HRESULT (0x80020005), что означает несоответствие типа disp. Итак, я был неправ, но не знаю, почему я получаю несоответствие.

ricky 04.04.2024 21:21
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
8
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключалась в добавлении флага ByRef к вызову Invoke. Это должен был быть только DISPATCH_METHOD.

Другими трудностями были:

  • Получение объекта Application Dispatch путем инициализации IUnknown и последующего приведения его к IDispatch. Это вызывало случайные исключения, которые не возникали при непосредственной инициализации как IDispatch.
  • Попытка использовать именованные аргументы вместо позиционных аргументов. Кажется, что большинство функций просто используют позиционные аргументы.

Другие вопросы по теме