// 1. Получаем исходный HTML из переменной ZennoPoster
string inputHtml = project.Variables["MyHtmlVariable"].Value;
// 2. Генерируем массив байт в строгой кодировке UTF-8 для Clipboard Windows
byte[] clipboardBytes = null;
try
{
// Используем UTF-8 без BOM-маркеров
UTF8Encoding utf8 = new UTF8Encoding(false);
// Шаблон официального заголовка Windows (каждое число занимает ровно 10 позиций)
string headerTemplate =
"Version:0.9\r\n" +
"StartHTML:{0

10}\r\n" +
"EndHTML:{1

10}\r\n" +
"StartFragment:{2

10}\r\n" +
"EndFragment:{3

10}\r\n";
string startHtml = "<html>\r\n<body>\r\n<!--StartFragment-->";
string endHtml = "<!--EndFragment-->\r\n</body>\r\n</html>";
// Считаем длину заголовка в байтах (он фиксированный и равен 105 байт)
int headerLength = 105;
int startHtmlPos = headerLength;
int startFragmentPos = startHtmlPos + utf8.GetByteCount(startHtml);
int endFragmentPos = startFragmentPos + utf8.GetByteCount(inputHtml);
int endHtmlPos = endFragmentPos + utf8.GetByteCount(endHtml);
// Заполняем заголовок точными байтовыми смещениями
string finalHeader = string.Format(headerTemplate, startHtmlPos, endHtmlPos, startFragmentPos, endFragmentPos);
// Собираем финальный текст в одну строку
string totalHtmlString = finalHeader + startHtml + inputHtml + endHtml;
// Превращаем всю конструкцию в сырой массив байт UTF-8
clipboardBytes = utf8.GetBytes(totalHtmlString);
}
catch (Exception ex)
{
project.SendWarningToLog("Ошибка подготовки HTML-байтов: " + ex.Message);
return "Ошибка подготовки";
}
// 3. Записываем байты напрямую в системный Clipboard внутри STA-потока с полными путями Windows Forms
Thread setClipboardThread = new Thread(() =>
{
try
{
System.Windows.Forms.DataObject dataObject = new System.Windows.Forms.DataObject();
// Передаем HTML как поток памяти (MemoryStream), содержащий UTF-8 байты.
using (MemoryStream ms = new MemoryStream(clipboardBytes))
{
dataObject.SetData(System.Windows.Forms.DataFormats.Html, ms);
// Добавляем Plain Text версию для страховки (очищаем от тегов)
string plainText = System.Text.RegularExpressions.Regex.Replace(inputHtml, "<.*?>", string.Empty).Trim();
if (string.IsNullOrEmpty(plainText)) plainText = " ";
dataObject.SetData(System.Windows.Forms.DataFormats.UnicodeText, plainText);
dataObject.SetData(System.Windows.Forms.DataFormats.Text, plainText);
System.Windows.Forms.Clipboard.Clear();
// Флаг true удерживает данные в памяти после завершения работы кубика C#
System.Windows.Forms.Clipboard.SetDataObject(dataObject, true);
}
}
catch (Exception ex)
{
project.SendWarningToLog("Ошибка записи в буфер обмена: " + ex.Message, true);
}
});
setClipboardThread.SetApartmentState(ApartmentState.STA);
setClipboardThread.Start();
setClipboardThread.Join();
return "Успешно! HTML скопирован в буфер обмена.";