one
Client
- Регистрация
- 22.09.2015
- Сообщения
- 7 015
- Реакции
- 1 310
- Баллы
- 113
У меня метод из старто поста уже сколько лет работает. Встявляет картинки в пост на ФБ. В конкурсах где то есть этот шаблон с этим методом.
запросто... просто посмотри какой лок используется в коде и сразу будет ясно в каких случаях он не будет работать.Хз как под локом он может пересечся. Или речь идет о пересечении при работе человека за пк?

Не врублюсь, а чем этот лок не подходит?запросто... просто посмотри какой лок используется в коде и сразу будет ясно в каких случаях он не будет работать.
не то что всегда не будет работать... но как всегда есть НО...
Видимо лок распределяется на один проект, а у людишек проекты одновременно работают с одним и тем же функционалом.Не врублюсь, а чем этот лок не подходит?
Нет, этот лок не работает на один проект.Видимо лок распределяется на один проект, а у людишек проекты одновременно работают с одним и тем же функционалом.
// Блокировка: True
// Построить путь к файлу
var lockFilePath = Path.Combine(project.Directory, "01 - The Base\01 - Cookies\The Lock.txt");
// Проверить, доступен ли буфер обмена
if (File.ReadAllText(lockFilePath) == "False")
{
// Буфер обмена доступен, записать "True", чтобы заблокировать его
File.WriteAllText(lockFilePath, "True");
}
else
{
// Подождите, пока буфер обмена не станет доступным
while (File.ReadAllText(lockFilePath) != "False")
{
// Подождите 1 секунду перед повторной попыткой
Thread.Sleep(1000);
}
// Как только буфер обмена станет доступным, записать "True", чтобы заблокировать его
File.WriteAllText(lockFilePath, "True");
}
Есть большая вероятность что при больших объемах потоков проект зациклиться и станет работать медленно, разумнее всего при итерации попыток вставки пробовать другие методы, такие как SET, либо эмуляцию клавиатуры на крайний вариантВоскресенье - время для отдыха, поэтому это Zenno:bo.
Использование буфера обмена в автоматизации следует избегать, но в некоторых случаях я использую его, потому что:
Эмуляция текста занимает слишком много времени (если установлен быстрый режим, текст не распознается/область текста не активирована). Для целей SEO, когда я не могу отправить HTML/разметку в качестве гостя. Чтобы избежать конфликтов в многопоточном использовании буфера обмена, я использую: lock(SyncObjects.InputSyncer), но это работает только во время выполнения блока C#.
Однако в некоторых случаях я выполняю операции копирования и вставки, между которыми есть несколько блоков, которые не являются пользовательскими блоками C# (и которые я не могу/не хочу преобразовывать). Поэтому на данный момент я использую простое решение: внешний файл, который действует как "блокировка" с булевым выбором, управляющим доступом к буферу обмена! Цель состоит в том, чтобы убедиться, что когда элемент копируется в буфер обмена, это не другой поток вставляет его, потому что между блоками есть задержка в несколько секунд, и может быть переплетение.
Я создал нижеуказанный код, что вы думаете об использованном методе?
Могло ли быть более простое/надежное решение?
C#:// Блокировка: True // Построить путь к файлу var lockFilePath = Path.Combine(project.Directory, "01 - The Base\01 - Cookies\The Lock.txt"); // Проверить, доступен ли буфер обмена if (File.ReadAllText(lockFilePath) == "False") { // Буфер обмена доступен, записать "True", чтобы заблокировать его File.WriteAllText(lockFilePath, "True"); } else { // Подождите, пока буфер обмена не станет доступным while (File.ReadAllText(lockFilePath) != "False") { // Подождите 1 секунду перед повторной попыткой Thread.Sleep(1000); } // Как только буфер обмена станет доступным, записать "True", чтобы заблокировать его File.WriteAllText(lockFilePath, "True"); }
Затем в конце процесса мы записываем "False" в текстовый файл.
Заранее спасибо за ваш совет!
![]()
PS :
Прошу прощения за возможные странности в моем русском тексте, я использую сервис перевода для своих сообщений. На данный момент я не владею русским языком, но с большим интересом и вниманием читаю русскую часть форума благодаря сервису перевода. Все ясно, что именно здесь, в русскоязычном сообществе, скрывается больше всего ценной информации. Так что, если я хочу продвинуться с Zenno, мне нужно отправиться на сторону русского сообщества!
На данный момент, единственное слово, которое я знаю на русском, это 'здоровье'


а буфер обмена как был один и не предназначеный для работы в многопотоке, так и осталсяДрузья, появилась новая инфа на счет вставки, но с помощью хот кеев. По сути метод прост: Устанавливаете софт который биндит хоткеи и эмулируете для каждого отдельного проекта с буфером обмена свой отдельный метод вставки. Так же возможно напрямую менять файл с вариацией вставки текста.![]()

Напитонил софт для вас, работает как с буфером так и с методом быстрой прописи текста, а так же есть настройка и пример. Не забудьте установить python с несколькими библиотеками, которые найдете в кодеДрузья, появилась новая инфа на счет вставки, но с помощью хот кеев. По сути метод прост: Устанавливаете софт который биндит хоткеи и эмулируете для каждого отдельного проекта с буфером обмена свой отдельный метод вставки. Так же возможно напрямую менять файл с вариацией вставки текста.![]()

что это меняет в глобальном смысле кроме того, что появился дополнительный костыль?Напитонил софт для вас, работает как с буфером так и с методом быстрой прописи текста, а так же есть настройка и пример. Не забудьте установить python с несколькими библиотеками, которые найдете в коде
Чтобы применить в инстансе необходима команда:
instance.ActiveTab.KeyEvent("Горячая клавиша", "press", "Клавиша с которой начинается комбинация");
Меняет то что теперь работает одна программа через которую проходит весь буфер обмена, вам теперь не нужно постоянно выполнять в каждом проекте и потоке кусок кода который отвечает за прерывание потока и установку текста в буфер. Все работает уже скомпилированным и тем является быстрым решением для многопоточного многопроектного проектища)что это меняет в глобальном смысле кроме того, что появился дополнительный костыль?
Единственный костыль с которым вы столкнетесь, это спам горячей клавиши если питон не включен.вы просто братья по несчастью, которые хотят быстрой и правильной работы от чего то одного. Так вот я предоставил вам несколько вариаций обхода неправильной логики дабы прийти к одному годному варианту.
Ах вы наши сладенькие, я вам в праве вообще не отвечатьничего не меняет... просто глянь его историю сообщений
думаю он тебе ответит примерно такхотя может преды научили общаться...
Посмотреть вложение 121190

любой код=часть природыбудто нейронка пишет
zenno.club
// Имя переменной ZennoPoster, содержимое которой нужно "вставить"
string variableName = "text_to_paste";
try
{
// 1. Получаем текст
string text = project.Variables[variableName].Value;
if (string.IsNullOrEmpty(text))
{
project.SendWarningToLog("[VirtualClipboard] Переменная пуста. Нечего вставлять.");
return "empty";
}
if (instance.ActiveTab.IsVoid)
{
throw new System.Exception("Активная вкладка недоступна.");
}
// 2. Безопасное экранирование текста для передачи в JavaScript
// Это гарантирует, что переносы строк, кавычки и слэши не сломают JS-код
string escapedText = text.Replace("\\", "\\\\")
.Replace("\"", "\\\"")
.Replace("\r", "")
.Replace("\n", "\\n");
// 3. Формируем JS-код виртуальной вставки
// Используем конкатенацию вместо string.Format, чтобы избежать ошибки с { и }
string jsCode = @"
(function() {
var textToPaste = """ + escapedText + @""";
var activeEl = document.activeElement;
// Проверяем, установлен ли фокус на какой-либо элемент ввода
if (!activeEl || activeEl.tagName === 'BODY') {
return 'no_focus';
}
// Основной метод: Нативная команда браузера.
// Вставляет текст единым куском (как Ctrl+V), не затрагивая буфер ОС
// и сохраняя возможность отмены (Undo/Ctrl+Z) в браузере.
var success = document.execCommand('insertText', false, textToPaste);
// Fallback-метод: Если сайт блокирует execCommand, симулируем вставку вручную
if (!success) {
var start = activeEl.selectionStart;
var end = activeEl.selectionEnd;
// Если это стандартное поле input или textarea
if (typeof start === 'number') {
var val = activeEl.value;
activeEl.value = val.slice(0, start) + textToPaste + val.slice(end);
activeEl.selectionStart = activeEl.selectionEnd = start + textToPaste.length;
// Триггерим события для активации React/Vue обработчиков
activeEl.dispatchEvent(new Event('input', { bubbles: true }));
activeEl.dispatchEvent(new Event('change', { bubbles: true }));
success = true;
}
// Если это contenteditable элемент (например, WhatsApp Web, WYSIWYG редакторы)
else if (activeEl.isContentEditable) {
activeEl.innerText += textToPaste;
activeEl.dispatchEvent(new Event('input', { bubbles: true }));
success = true;
}
}
return success ? 'ok' : 'fail';
})();
";
// 4. Выполняем скрипт внутри контекста браузера текущего потока
string result = instance.ActiveTab.MainDocument.EvaluateScript(jsCode);
// 5. Обработка результатов
if (result == "no_focus")
{
throw new System.Exception("Ни один элемент на странице не находится в фокусе. Перед вставкой необходимо кликнуть в нужное поле.");
}
if (result == "fail")
{
throw new System.Exception("Браузер отклонил виртуальную вставку. Возможно, активный элемент не поддерживает текстовый ввод.");
}
project.SendInfoToLog("[VirtualClipboard] Текст успешно вставлен (Изолированно от ОС).");
return "ok";
}
catch (System.Threading.ThreadAbortException)
{
project.SendWarningToLog("[VirtualClipboard] Выполнение прервано пользователем.");
return "aborted";
}
catch (System.Exception ex)
{
project.SendErrorToLog("[VirtualClipboard] Критическая ошибка: " + ex.Message);
return "error";
}
А чем это профессиональное решение отличается кардинально например от вот этого?Существует профессиональное и полностью изолированное решение. Создание виртуального буфера обмена с помощью нативного JavaScript API.
Скрипт ниже берет значение из переменной ZennoPoster и применяет браузерную команду insertText к активному (выделенному) элементу. Для сайта (включая сложные фреймворки вроде React или Vue) это выглядит в точности как вставка из буфера обмена единым блоком. При этом:
- Системный буфер обмена Windows вообще не используется.
- Потоки работают на 100% независимо и никогда не пересекаются.
- Корректно срабатывают все события input и change на сайте.
C#:// Имя переменной ZennoPoster, содержимое которой нужно "вставить" string variableName = "text_to_paste"; try { // 1. Получаем текст string text = project.Variables[variableName].Value; if (string.IsNullOrEmpty(text)) { project.SendWarningToLog("[VirtualClipboard] Переменная пуста. Нечего вставлять."); return "empty"; } if (instance.ActiveTab.IsVoid) { throw new System.Exception("Активная вкладка недоступна."); } // 2. Безопасное экранирование текста для передачи в JavaScript // Это гарантирует, что переносы строк, кавычки и слэши не сломают JS-код string escapedText = text.Replace("\\", "\\\\") .Replace("\"", "\\\"") .Replace("\r", "") .Replace("\n", "\\n"); // 3. Формируем JS-код виртуальной вставки // Используем конкатенацию вместо string.Format, чтобы избежать ошибки с { и } string jsCode = @" (function() { var textToPaste = """ + escapedText + @"""; var activeEl = document.activeElement; // Проверяем, установлен ли фокус на какой-либо элемент ввода if (!activeEl || activeEl.tagName === 'BODY') { return 'no_focus'; } // Основной метод: Нативная команда браузера. // Вставляет текст единым куском (как Ctrl+V), не затрагивая буфер ОС // и сохраняя возможность отмены (Undo/Ctrl+Z) в браузере. var success = document.execCommand('insertText', false, textToPaste); // Fallback-метод: Если сайт блокирует execCommand, симулируем вставку вручную if (!success) { var start = activeEl.selectionStart; var end = activeEl.selectionEnd; // Если это стандартное поле input или textarea if (typeof start === 'number') { var val = activeEl.value; activeEl.value = val.slice(0, start) + textToPaste + val.slice(end); activeEl.selectionStart = activeEl.selectionEnd = start + textToPaste.length; // Триггерим события для активации React/Vue обработчиков activeEl.dispatchEvent(new Event('input', { bubbles: true })); activeEl.dispatchEvent(new Event('change', { bubbles: true })); success = true; } // Если это contenteditable элемент (например, WhatsApp Web, WYSIWYG редакторы) else if (activeEl.isContentEditable) { activeEl.innerText += textToPaste; activeEl.dispatchEvent(new Event('input', { bubbles: true })); success = true; } } return success ? 'ok' : 'fail'; })(); "; // 4. Выполняем скрипт внутри контекста браузера текущего потока string result = instance.ActiveTab.MainDocument.EvaluateScript(jsCode); // 5. Обработка результатов if (result == "no_focus") { throw new System.Exception("Ни один элемент на странице не находится в фокусе. Перед вставкой необходимо кликнуть в нужное поле."); } if (result == "fail") { throw new System.Exception("Браузер отклонил виртуальную вставку. Возможно, активный элемент не поддерживает текстовый ввод."); } project.SendInfoToLog("[VirtualClipboard] Текст успешно вставлен (Изолированно от ОС)."); return "ok"; } catch (System.Threading.ThreadAbortException) { project.SendWarningToLog("[VirtualClipboard] Выполнение прервано пользователем."); return "aborted"; } catch (System.Exception ex) { project.SendErrorToLog("[VirtualClipboard] Критическая ошибка: " + ex.Message); return "error"; }
Оба скрипта решают одну глобальную задачу — изоляцию потоков от системного буфера обмена ОС Windows.Но первый скрипт нужен для безопасного ЧТЕНИЯ с сайта (копирование), а второй — для безопасной ЗАПИСИ на сайт (вставка). Используя их вместе, вы получаете полностью замкнутый и независимый буфер обмена внутри конкретного потока браузера.А чем это профессиональное решение отличается кардинально например от вот этого?


