Убить процесс конкретного окна 1С




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

36 Comments

  1. Abadonna

    Иногда невозможно закрыть окно 1С программно из самой 1С (например, имеются модальные окна типа вопрос и предупреждение). В таких случаях применяется внешняя программа, убивающая процесс по имени создавшего его файла. Но в таком случае будут завершены все процессы (закрыты окна), созданные этим файлом (например, все запущенные базы и конфигураторы). Настоящая программа «убивает» процесс избирательно, по заголовку окна принадлежащего этому процессу

    Перейти к публикации

    Reply
  2. jhfrek

    Гениально! Супер!

    Reply
  3. Abadonna

    Пример применения для 7.7 с использованием Formex.dll:

    Прелесть метода ОбработкаОжидания объекта "Сервис" этой библиотеки заключается в том, что он отрабатывает всегда, независимо от наличия в системе модальных окон.

    В ГМ или ДопГМ добавляем строчку:

    Код
    Сервис.ОбработкаОжидания("глУбить1С",60000);// например, 1 минута

    Показать полностью

    Прописываем процедуру:

    Код
    Процедура глПроверитьУбить1С()
       Если ФС.СуществуетФайл(КаталогИБ()+"kill.out") =1 Тогда // например, просто проверим наличие такого файла  
          //так не сработает при наличии модального окна
          //ЗавершитьРаботуСистемы(0);       
          ЗапуститьПриложение(КаталогИБ()+"Kill1CProcWnd.exe");  // так сработает ;)         
       КонецЕсли;
    КонецПроцедуры
    

    Показать полностью

    Reply
  4. Abadonna

    +(2) Сорри, опечатка после копирования… 😉

    [code]Процедура глУбить1С()[/b] должно быть

    Reply
  5. Abadonna

    Проверил под 8-кой. В отличие от 77 там ПодключитьОбработчикОжидания отрабатывает при наличии окон типа Вопрос и Предупреждение. Не отрабатывает только, если открыт диалог выбора файла.

    Примерный код для "изнутри" в 8-ке

    Код
    Процедура глУбить1С() Экспорт
       Каталог="c:\V8_Бухгалтерия1_6_8_3"; // для файловой системы можно получить тек. каталог базы через   СтрокаСоединенияИнформационнойБазы();
       Файл = Новый Файл(Каталог+"\kill.out");
       Если Файл.Существует()=Истина Тогда
          ЗапуститьПриложение("Kill1CProcWnd.exe",Каталог,Истина);
       КонецЕсли;   
    КонецПроцедуры
    Процедура ПриНачалеРаботыСистемы()
            //...........................................
            ПодключитьОбработчикОжидания("глУбить1С",60,Ложь);
    КонецПроцедуры
    

    Показать полностью

    Reply
  6. BabySG

    Эээээ…. Такие зависшие окна, типа предупреждения, появляются от неграмотной разработки. Там даже есть параметр специальный для автозакрытия.

    Действительно для 8.х, но, полагаю, и в 77 тоже самое.

    Reply
  7. ValeriVP
    Reply
  8. Abadonna

    ()>типа предупреждения, появляются от неграмотной разработки.

    Немного неправильно полагаешь 😉 Любой док в 77 просто обязан спросить Сохранить?Закрыть?

    Плюс, например, брошенное «на произвол судьбы» окно авторизации доступа. Плюс всякие предупреждения от разработчиков (самой 1С), не перелопачивать же весь код за ними.

    Reply
  9. Abadonna

    (6)>Процесс может быть завершен по имени образа или по идентификатору процесса.

    Позволь узнать а откуда ты PID возмешь? И вас ис дас Имя образа процесса?

    Если ты внимательно читал, то «notepad.exe » не катит, если я хочу закрыть именно этот блокнот, а не ваще все блокноты. И чем спортивно писать корявые скрипты, когда эта прога все спокйно делает сама: ищет и PIDы, и хэндлы завершения процесса, и все окна данного процесса.

    Reply
  10. ValeriVP

    (8) это все не обязательно, если ты внимательно читал 🙂

    попробуй закрыть блокнот например так:

    taskkill /fi «windowtitle eq 1.txt — Блокнот»

    Reply
  11. Abadonna

    (9) Тогда скажи в чем разница написать строчку в ini-файл с заголовком окна, или написать строчку такого скрипта?

    Reply
  12. Abadonna

    (9) Ну вот, проверил. «Спокойный» блокнот мочит, а вот блокнос с вопросом «Текст…измененен.. сохранить?» при отработке твоего скрипта вызывает еще одно такое же окно c тем же вопросом. Если бы стояла задача просто замочить окно, то фигли париться? Послал SendMessage(hwnd, WM_CLOSE,0,0) — и всех дел

    Reply
  13. ValeriVP

    (10) разница в необходимости дополнительных компонентов для работы системы

    (11) тогда попробуй закрыть блокнот так:

    [b]taskkill /f /fi «windowtitle eq 1.txt — Блокнот»

    Reply
  14. Abadonna

    (12) По последнему варианту — согласен, мочит.

    Ну а насчет «дополнительных компоненов» — несогласен. Мало ли каких прог в Винде работает?

    Эта пить-есть не просит, и в памяти какие-то миллисекунды торчит

    Reply
  15. Abadonna

    +(13) Кстати, 7.7 с торчащим предупреждение не мочит.

    Заголовок окна — 1С:Предприятие — БД: C:УпрОтладка , торчит Предупреждение

    taskkill /f /fi «windowtitle eq 1С:Предприятие — БД: C:УпрОтладка» — правильно написал?

    Reply
  16. ValeriVP

    (13) дополнительные компоненты — зло, когда можно без них обойтись.

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

    а один самый умный тут уже есть, зачем нам два?

    Reply
  17. Abadonna

    На 14 ответь

    Reply
  18. Abadonna

    (15)>а один самый умный тут уже есть, зачем нам два?

    Кстати, любителей «простых решений» ту еще больше :)))

    Reply
  19. Abadonna

    +(14) Оно вообще не убивает окно с таким титлом. Либо я неправильно написал скрипт, хотя точно по аналогии, либо….

    Reply
  20. ValeriVP

    так попробуй

    taskkill /f /fi «windowtitle eq 1С:Предприятие — БД: C:УпрОтладка «

    Reply
  21. Abadonna

    (18)Угум, и тут согласен. Только одно непонятно: я заголовок брал со spyxx мелксофтовского, а он возвращает титлы с пробелами (там пробела в конце не было). При этом моя с ini-строчкой без пробела на конце (trim) убивает, у тут как угадать сколько пробелов в конце добавить?

    Reply
  22. ValeriVP

    (20) не нравится ему последний символ «». если в командной строке после него ставить пробел или второй такой-же — нормально работает. наверно он рассматривает этот символ как подстановочный. вот только доки найти не могу

    Reply
  23. Abadonna

    (21)>не нравится ему последний символ «»

    Ну вот 😉 Бум считать, что моя для не особо продвинутых, которым не надо заморачиваться какие символы не нравятся команде taskkill 😉

    Reply
  24. Abadonna

    +(22) Кстати, когда писал гарббер статус-строки для конфигуратора и 1С, товарисч Чебурашка мне ТАКИЕ титлы подкитывал, с ТАКОЙ тучей знаков препинания и черт еще чем, что, думаю,

    у taskkill точно бы крышак съехал :))))

    Reply
  25. Abadonna

    +(23) Я ж любопытный! 😉

    Попробовал такой титл 1С:Предприятие — БД: C:УпрОтладка*-

    Ни с пробелом на конце, ни с пробелом после обратного флеша не отрабатывает taskkill

    А уж чаво могут люди в ЗаголовоСистемы навтыкать —

    Reply
  26. ValeriVP

    (22) ну вот, после серии опытов было выяснено — можно taskill ставить просто дополнительный пробел (или несколько) в фильтре (в конце), и все работает.

    Reply
  27. Abadonna

    (24) ты, видать, не успел прочесть 😉

    Reply
  28. ValeriVP

    (24)доку надо

    Reply
  29. CheBurator

    а убивается по точному заголовку или по вхождению сигнальной строки в заголовок?

    Reply
  30. Abadonna

    Моя убивает по точному, но можно приделать и по вхождению (целую строчку в код дописать:))

    А вот как taskkill — не знаю… Видишь, какие-то нюансы там получаются… То ему то не нравится, то это…

    Reply
  31. Abadonna

    +(29) По вхождению — все-таки плохо.

    Например, у меня открыты базы с заголовоками: Моя база и Моя База *

    Предположим, я эту зведочку использую, чтобы отличить рабочую от отладочной.

    По вхождению — замочатся обе, а мне этого как

    Reply
  32. WolfhounD

    Извини, а исходники exe не мог бы выложить?

    Reply
  33. Fisherru

    (29) Не очень хорошо по точному.

    Не то чтобы плохо, но у меня не катит 🙁

    Я в заголовок системы ещё год базы запихиваю и путь

    СтарыйЗаголовок = ЗаголовокСистемы();

    ЗаголовокСистемы(СтарыйЗаголовок+Строка(Константа.ГодБазы)+» < «+СокрЛП(КаталогИБ())+» > «);

    так как базы время от времени обрезаются, а рабочая конфа всегда одна,

    (30) а по расположению базы отличаю : рабочая — живая.

    Так и не сумел поймать комбинацию, чтоб такой наворот эта программа кончала.

    (30) Кстати, группе админов я такое ожидание просто не включаю 😉

    В общем бился я бился, так и не сумел точно изобразить заголовок окна,

    после 5-го эксперимента… 🙁

    Можно мне вариант по вхождению?

    Очень надо…

    И, ещё, когда мы использовали команду

    ЗавершитьРаботуСистемы() на SQL-ной базе, как-то раз случилось, что какой-то процесс подвис на серваке и никто не мог войти в базу. Наши админы намаялись исправляя ситуацию. С тех пор боимся пользовать подобное выгоняние.

    А вот Kill1CProcWnd.exe корректно отработает? не будет проблем с SQL-лем?

    Reply
  34. Abadonna

    По просьбе добавил версию 1.2 — «убиение» по вхождению строки из ini-файла в заголовок окна. Для запуска по вхождению запускать программу с ключом

    /in. При запуске без ключа — будет работать только по полному совпадению

    Reply
  35. Fisherru

    (33) Спасибо

    Reply
  36. Sergey_Murzinov

    Помогает спасать некоторых бухгалтеров (перед окончанием дня ставят отчеты)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *