GetDataObject Запрошенная операция буфера обмена не завершилась успешно 0x800401D0

Я сделал надстройку для Excel (2016), которая сохраняет область печати как файл jpg. Несколько месяцев он работал нормально. В настоящее время я получаю все больше и больше отчетов об ошибках от пользователей, все они получают одну и ту же ошибку (рисунок ниже). У пользователей Windows 7 с Excel 2013 или Windows 10 с Excel 2016, у обоих есть эта ошибка. Сначала помогла переустановка программы, но теперь уже не помогает.

введите описание изображения здесь

Вот мой код:

public static void Save(string report, string area, RibbonControlEventArgs e)
{
    Excel.Window window = e.Control.Context;
    Excel.Worksheet sheet = ((Excel.Worksheet)window.Application.ActiveSheet);
    Excel.Range range = sheet.Range[sheet.PageSetup.PrintArea];

    range.CopyPicture(Excel.XlPictureAppearance.xlPrinter, Excel.XlCopyPictureFormat.xlPicture);
    range.Copy(Type.Missing);

    string fileName = @"\\server.company.lan\report.jpg";

    if (Clipboard.GetDataObject() != null)
    {
        IDataObject data = Clipboard.GetDataObject();

        Image image = (Image)data.GetData(DataFormats.Bitmap, true);
        image.Save(fileName, ImageFormat.Jpeg);
    }
}

person Adam    schedule 03.08.2017    source источник
comment
Вы используете это в потоке, отличном от STA? (PS: тип Exception может серьезно помочь ...) также проверьте это: stackoverflow.com/questions/68666/   -  person Simon Mourier    schedule 07.09.2017
comment
@SimonMourier Да, я использую это в потоке, отличном от STA. Я прикрепил сообщение об ошибке к своему вопросу, это все, что у меня есть, потому что я не могу воспроизвести эту ошибку на своем компьютере.   -  person Adam    schedule 07.09.2017
comment
Для доступа к буферу обмена необходимо использовать поток STA.   -  person Simon Mourier    schedule 07.09.2017
comment
@SimonMourier Это работает! Спасибо за помощь!   -  person Adam    schedule 08.09.2017


Ответы (1)


Весь доступ к буферу обмена должен выполняться с использованием потока STA. Для этого есть много способов:

  • используйте функции BeginInvoke (Winforms или WPF), которые гарантируют код работает в потоке пользовательского интерфейса (который должен быть STA)
  • запустите собственный экземпляр потока и используйте SetAparmentState (STA),
  • и Т. Д.
person Simon Mourier    schedule 08.09.2017