Перетаскивание виртуальных файлов с помощью IStream с использованием VirtualFileDataObject не работает с Outlook версии 16.0.12730 - PullRequest
1 голос
/ 30 мая 2020

У моего приложения проблема с апрельским обновлением Office.

У меня есть приложение, которое поддерживает функцию перетаскивания. Пользователи могут перетаскивать элементы из списков документов в проводник или в текст черновиков электронных писем и добавлять документы во вложения. Для выполнения sh этого я использовал код VirtualFileDataObject из блога Delay , используя перегрузку Action<Stream> SetData. Это отлично работало до апрельского обновления Office 2020.

Но после апрельского обновления Office с версией Office 16.0.12730 это больше не работает. Перетаскивание не добавляет элементы документа во вложение.

Я могу хорошо воспроизвести эту проблему с помощью демонстрационного примера приложения из блога Delay . Загрузите исходный код VirtualFileDataObject из блога Delay и запустите VirtualFileDataObjectDemo. В диалоговом окне перетащите третью кнопку «виртуальный файл» в тело черновика электронного письма. Затем файл добавляется во вложения.

Это работает только в Outlook перед апрельским обновлением Office 2020. Если вы устанавливаете апрельское обновление Office 2020. У вас установлена ​​версия Outlook 16.0.12730. Теперь повторите процесс, файлы не добавляются во вложения.

Соответствующий раздел кода VirtualFileDataObject находится ниже.

public void SetData(short dataFormat, int index, Action<Stream> streamData) 
{
        _dataObjects.Add(
            new DataObject {
                FORMATETC = new FORMATETC {
                    cfFormat = dataFormat,
                    ptd = IntPtr.Zero,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex = index,
                    tymed = TYMED.TYMED_ISTREAM
                },
                GetData = () => {
                    // Create IStream for data
                    var ptr = IntPtr.Zero;
                    var iStream = NativeMethods.CreateStreamOnHGlobal(IntPtr.Zero, true);
                    if (streamData != null) {
                        // Wrap in a .NET-friendly Stream and call provided code to fill it
                        using (var stream = new IStreamWrapper(iStream)) {
                            streamData(stream);
                        }
                    }
                    // Return an IntPtr for the IStream
                    ptr = Marshal.GetComInterfaceForObject(iStream, typeof(IStream));
                    Marshal.ReleaseComObject(iStream);
                    return new Tuple<IntPtr, int>(ptr, NativeMethods.S_OK);
                },
            });
    }
...