Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Здравствуйте
Программно создаю (точнее заполняю готовую форму файла Excel) товарную накладную. Методика: в папке с формами хранится Excel шаблон, программа копирует его в tmp-папку с tmp-именем, открывает эту копию и заполняет. Причем Excel становится видимым
Если вдруг во время этого процесса что-то произошло (не корректные данные и пр.), то программа "вылетает". а Excel-процесс с tmp-именем остаётся "висеть" невидимым и при следующей попытке копирования шаблона в tmp-папку с tmp-именем возникает ошибка. Программа выводит соответствующее сообщение. Изначально делалось для себя, я открывал Диспетчер и убивал процесс. Но теперь пользуются другие и начинают орать "все пропало!" Естественно методика не выдерживает критики, но самое простое решение - убить этот скрытый процесс и, ничего не сообщая, создать новый. Поэтому: 1. Я легко получаю HWND этого окна 2. Легко его могу сделать видимым (но Юзеру придется превозмогая страх и непонимание его закрыть не сохраняя) 3. Легко могу послать
4. Никак не могу убить этот процесс по HWND Пытаюсь делать так:
? Исправлено 2 раз(а). Последнее : Sandwich, 17.09.21 00:30 |
Re: Убить насмерть Excel процесс | |
---|---|
PuMa Сообщений: 153 Откуда: Комсомольск-на-А Дата регистрации: 19.04.2006 |
Проще всего, наверное, поместить процесс заполнения в TRY и в его секции CATCH выдать пользователю сообщение об ошибке и корректно закрыть Excel
m.loExcel.DisplayAlerts = .f. m.loExcel.Quit() |
Re: Убить насмерть Excel процесс | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Можно прибивать по имени процесса через скрипты, обычно без проблем. Типа так:
------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Убить насмерть Excel процесс | |
---|---|
ssa Сообщений: 13007 Откуда: Москва Дата регистрации: 23.03.2005 |
То есть "стандартный" закат солнца вручную. Хотя есть не менее стандартные и давно встроенные в сами офисные пакеты методы работы с шаблонами. Но подавляющее большинство народу таки предпочитает сколхозить что-нить свое. К тому же уже есть и способы создания Excel файлов без использования Excel. ------------------ Лень - это неосознанная мудрость. |
Re: Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Просто программа рождена еще в самом начале этого века. Ну очень не хочется переделывать. |
Re: Убить насмерть Excel процесс | |
---|---|
Равиль Сообщений: 6549 Откуда: Уфа Дата регистрации: 01.08.2003 |
Заброшенные при сбоях Excel-процессы - явление довольно частое, но тут не понятно почему возникает ошибка, если шаблон копируется с уникальным именем :
Может кусочек кода этого копирования и открытия покажете ? ------------------ Тяжело согнать курсором муху с монитора ... |
Re: Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Имя файла не уникально, оно содержит номер документа
|
Re: Убить насмерть Excel процесс | |
---|---|
Равиль Сообщений: 6549 Откуда: Уфа Дата регистрации: 01.08.2003 |
Так и думал, это приведет ко многим проблемам, например если 2 пользователя захотят одновременно создать один и тот же документ ? Добавьте хотя бы sys(2015) к имени файла и не придется ловить процессы и убивать file_name = 'счет_'+alltrim(str(doc.nomer))+sys(2015)+'.xlsx' Или работайте с файлом во временной папке и уже потом сохраняйте его в общую. ------------------ Тяжело согнать курсором муху с монитора ... |
Re: Убить насмерть Excel процесс | |
---|---|
AleksM Сообщений: 17881 Дата регистрации: 11.11.2003 |
Работать нужно через шаблоны, в полном понимании этого слова в парадигме офиса.
Обсуждение по данному поводу можно найти через поиск. ------------------ Лучше переесть, чем недоспать. Не спеши, а то успеешь. |
Re: Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Друзья, я в первом посте написал
Ваши замечания, безусловно, по делу. Но ведь вопрос стоит более широко: я не умею убивать процессы (и не важно Excel или нет, формы, парадигмы, юзеры, разделения полномочий и пр.) убивает все Открытые Excel окна, а скрытый процесс продолжает висеть Пока ковыряю в эту сторону. Если ставлю
|
Re: Убить насмерть Excel процесс | |
---|---|
ssa Сообщений: 13007 Откуда: Москва Дата регистрации: 23.03.2005 |
Это не умеют делать подавляющее большинство программистов. Ибо нефиг. Это лечение последствий, а не причин. Но именно переделыванием кое-кто таки сейчас и занимается. К тому же, рекомендуемая переделка не такая уж и большая и сложная. ------------------ Лень - это неосознанная мудрость. |
Re: Убить насмерть Excel процесс | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Бороться надо не с последствиями, а с причиной
У Вас произошел сбой при выполнении некой операции в FoxPro. Для перехвата таких ситуаций есть конструкция TRY...CATCH
|
Re: Убить насмерть Excel процесс | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Ну я же писал выше про "имя документа". Помнится убивался процесс именно по имени файла, который сам же и создаешь программно. Т.е. не надо было выковыривать откуда-то имя процесса - просто этой же переменной, что и при создании документа воспользоваться. И все прибивалось. В принципе же - приведенные здесь советы по переделке программы все же более корректны могли бы оказаться. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Убить насмерть Excel процесс | |
---|---|
of63 Автор Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
Вот тут пишут как получить PID потока, и как его убить, на примере Excel
Часть текста скрыта
stackoverflow.com
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId); Process GetExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp) { int id; GetWindowThreadProcessId(excelApp.Hwnd, out id); return Process.GetProcessById(id); } void TerminateExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp) { var process = GetExcelProcess(excelApp); if (process != null) { process.Kill(); } } private void button1_Click(object sender, EventArgs e) { // Create Instance of Excel Microsoft.Office.Interop.Excel.Application oXL = new Microsoft.Office.Interop.Excel.Application(); try { // Work with oXL } finally { TerminateExcelProcess(oXL); } } везде пишут axforum.info Исправлено 1 раз(а). Последнее : of63, 17.09.21 16:23 |
Re: Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Всем большое спасибо за ответы.
Не подумайте, что я уперся и не слушаю: я сделал и то, и это: 1. Разобрался и сделал функцию, которая при необходимости может убить любой процесс (видимый или не видимый) 2. Переделал функционал, используя TRY...CATCH Еще раз спасибо |
Re: Убить насмерть Excel процесс | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Убивать процесс нехорошо уже хотя бы потому что потом, при очередном старте экселя он может предложить "восстановить файл после сбоя".
"Развести" генерируемые файлы с одним и тем же именем можно, создавая их в разных подпапках %TEMP% - имена подпапок уже сделать не одинаковыми (случайными, или последовательными типа 1,2,3...) Если вдруг штатного функционала перехвата и обработки ошибок (try ... catch, on error ...) окажется недостаточно (это возможно, если ошибка будет связана с крахом фоксового процесса - а эксель будет вполне себе продолжать работать), то можно попытаться "подключиться" к уже запущенному эксель-процессу, используя GETOBJECT(,"Excel.Application") и как-то "разрулить" ситуацию - например найти и закрыть недоформированный документ. Главное держать в уме, что таким образом можно запросто вломиться в интерактивный экселевский процесс запущенный самим пользователем (а что-то делать с его документами не есть хорошо). Как общая рекомендация к програмной работе с экселем - формировать документ (заполнять шаблон) стоит в отдельной, независимой копии экселя (созданной по CreateObject("Excel.Application") и по возможности максимально "изолированной" от взаимодействия с пользователем - подавить все предупреждения, заблокировать "внешние запросы", НЕ делать окно видимым). По завершению формирования документа сохранить его в нужное место под нужным именем и завершить рабочий экселевский процесс. Затем "открыть" на просмотр готовый документ при помощи ShellExecute() или иным способом - уже в "обычной" копии экселя, возможно запущенной ранее самим пользователем - без контроля над тем что там будет пользователь с этим документом делать (это тоже не всегда возможно, но если нет требований "следить" за юзером и тем что он с документом делает, то будет норм). ------------------ WBR, Igor |
Re: Убить насмерть Excel процесс | |
---|---|
Sandwich Сообщений: 137 Дата регистрации: 08.02.2014 |
Он и предлагает, доработаю. А если в нужном месте с нужным именем есть и открыт предыдущий файл, да еще и в процессе корректировки данных? тут уже без юзера не обойтись. Пишу и сам думаю: а я ведь до начала формирования проверяю такое событие и активирую такое окно. Спасибо за советы |
Re: Убить насмерть Excel процесс | |
---|---|
andrewk Сообщений: 174 Откуда: Красноярск Дата регистрации: 15.05.2005 |
Проблема может быть не только в программной ошибке. Например, если офис палёный, то через несколько секунд (не сразу) после запуска экселя он выводит окно насчёт активации, которое полностью блокирует его работу. Но, поскольку в нашем случае loExcel.Visible=.F., то и это окно не видно. А у нас, насколько помню, через некоторое время вылетает что-то мутное типа "ole не отвечает".
В более свежих версиях, насколько помню, ситуация изменилась. Но в Excel-2007 (только что проверил под WinXP) получается вот что: Если процесс заполнения относительно долгий, и за это время юзер успел открыть какой-то «свой» Excel, то в диспетчере задач новый процесс не появляется. Более того, наш невидимый эксель становится видимым, и человек может чего-то делать – и в своём, и в нашем. Заблокировать его телодвижения можно с помощью loExcel.Interactive=.F.. Или даже loExcel.ScreenUpdating=.F., но так юзер совсем напугается. Если же не блокировать, то, возможно, юзер чего-то нарисовал, а по командам Close+Quit «его» эксель тоже молча закроется, без сохранения. Думаю, лучше как-то так:
Наверное, имелось ввиду loBook.Saved, но это, вроде, лишнее. |
Re: Убить насмерть Excel процесс | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Для борьбы с этим я в своё время сразу же после получения ссылки на объект экселя делал:
А последняя строка как раз и отключает DDE в экселе, и винда не сможет при открытии excel файла в проводнике "достучаться" до нашей копии Единственный косяк с этим подходом состоит в том, что эта настройка весьма "глобальная", и может вообще поломать открытие файлов в экселе, если её не сбросить обратно в .F. перед окончанием программной работы с экселем (т.е. вдвойне важно чтобы эксель не умирал, не зависал и корректно доходил до завершения - пусть и в блоке обработки ошибок - чтобы мы могли вернуть этот флажок в исходное положение). ------------------ WBR, Igor |
Re: Убить насмерть Excel процесс | |
---|---|
of63 Автор Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
> Единственный косяк с этим подходом состоит в том, что эта настройка весьма "глобальная", и может вообще поломать открытие файлов в экселе, если её не сбросить
Поэтому лучше его просто убить. () Эксель и правда, висит в процессах долго, после штатного закрытия, вроде не вечно, но висит... что-то делает... и мешает морально! ) |
© 2000-2024 Fox Club  |