Как получить Html из буфера обмена в формате Unicode?

493
03 февраля 2017, 03:22

Программа берет содержание буфера(Хранится Html) должна сделать над ним какую-то работу.

Но проблема в том, что в нем кириллица=> нужно что-то делать с кодировкой...

Пробовал перекодировать , но у некоторых пользователей возникают кракозябры:

var bytes=Encoding.Default.GetBytes(source);         
return Encoding.UTF8.GetString(bytes);

Пробовал Html из буфера, который вызывает одних кракозябры сам прогонять через программу и у меня все нормально.

Может дело в каких-то настройках Windows?

Какие существуют более универсальные варианты перекодирования?

Все пользователи(в том числе и я) используют Google Chrome=> это не проблема браузера.

Answer 1

Понятие кодировки возникает только при сохранении строки на диск (в виде отдельных байт) или при передачи по сети (в виде байт).

То, что вы считаете ситуацией "строка source в неправильной кодировке" - это ложная проблема. Т.к. проблема кодировки возникает только при преобразовании в байты - то на самом деле ваша проблема это

"строка source была прочитана из массива байт с указанием неправильной кодировки".

И править надо это не "перекодированием". После прочтения строки из байт с использованием неправильной кодировки нет 100% рабочего способа ее "исправить". Есть только костыли вроде "записать ее назад в байты с указанием неправильной кодировки (надеясь что байты получатся те же самые), а потом еще раз прочитать с указанием правильно". Т.е. вы пытаетесь построить цепочку:

  1. Есть байты строки в кодировке A
  2. Прочитать их как строку в кодировке B
  3. Увидеть кракозяблы
  4. Записать кракозяблы обратно с указанием кодировки B (использовать операцию, обратную (2) надеясь получить оригинальные байты, те же, что были в (1)
  5. Прочитать байты (те же, что были в (1)) в строку, но уже с указанием кодировки A

Код в вашем примере делает пункты 3-5. Код для 1-2 вы не привели. При этом очевидно, что в полной цепочке пункты 2-4 избыточны, и выглядеть она как

  1. Есть байты строки в кодировке A
  2. Прочитать байты в строку с указанием кодировки A

Вам нужно исправить то место, где вы читаете source из массива байт/из сети/из буфера обмена, указав в нем правильную кодировку. "Перекодирование стоит использовать только в случае, если вы получаете кривую строку сразу в виде string из стороннего источника.

К сожалению, Cliboard.GetText(TextDataFormat.Html) - это именно такой источник.

HTML Clipboard Format выдает содержимое в виде байт именно в UTF-8.

Реализация чтения байт в HTML-строку в Cliboard выглядит вот так:

if (format.Equals(DataFormats.Text)
    || format.Equals(DataFormats.Rtf)
    || format.Equals(DataFormats.OemText)) {
    data = ReadStringFromHandle(hglobal, false);
}
else if (format.Equals(DataFormats.Html)) {
    if (WindowsFormsUtils.TargetsAtLeast_v4_5) {
        data = ReadHtmlFromHandle(hglobal);
    }
    else {
        // This will return UTF-8 strings as an array of ANSI characters, which makes it the wrong behavior.
        // Since there are enough samples online how to workaround that, we will continue to return the
        // incorrect value to applications targeting netfx 4.0
        // DevDiv2 
        data = ReadStringFromHandle(hglobal, false);
    }
}

Собственно, комментарий полностью объясняет поведение.

  • при компиляции под 4.5 и более поздние фреймворки вы получите сразу валидную строку
  • при компиляции под 4.0 и более ранние версии - вы получите получите байты в UTF-8, прочитанные как Encoding.Default, через new string((sbyte*)ptr)

Соответственно, в <=4.0 ваш хак с перекодированием обязателен и полностью валиден. В >=4.5 он гаранитированно невалиден и избыточен.

READ ALSO
Скорректировать изображение C#

Скорректировать изображение C#

Проблема такова, стояла задача в вырезании объекта из фонаПосле всех манипуляций получилось вот что

390
Запуск макроса Excel из c#

Запуск макроса Excel из c#

Добрый деньЕсть файл excel, в котором прикручена кнопка

491
Предупреждение в VS в проекте .NET Core

Предупреждение в VS в проекте .NET Core

Предупреждение появляется при использовании любого типа из BCL в проектахNET Core

409
Создание дочернего объекта из префаба

Создание дочернего объекта из префаба

Из префаба в цикле создаются объекты:

443