for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Лисоводы   всех   стран,  объединяйтесь !!!  

Список Форумов  :: Visual Foxpro, Foxpro for DOS
  

Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 17.09.21 00:19:19
Здравствуйте
Программно создаю (точнее заполняю готовую форму файла Excel) товарную накладную.
Методика: в папке с формами хранится Excel шаблон, программа копирует его в tmp-папку с tmp-именем, открывает эту копию и заполняет. Причем Excel становится видимым
m.loExcel.Visible= .T.
только в самом конце процесса заполнения.
Если вдруг во время этого процесса что-то произошло (не корректные данные и пр.), то программа "вылетает". а Excel-процесс с tmp-именем остаётся "висеть" невидимым и при следующей попытке копирования шаблона в tmp-папку с tmp-именем возникает ошибка. Программа выводит соответствующее сообщение.
Изначально делалось для себя, я открывал Диспетчер и убивал процесс.
Но теперь пользуются другие и начинают орать "все пропало!"
Естественно методика не выдерживает критики, но самое простое решение - убить этот скрытый процесс и, ничего не сообщая, создать новый.
Поэтому:
1. Я легко получаю HWND этого окна
2. Легко его могу сделать видимым (но Юзеру придется превозмогая страх и непонимание его закрыть не сохраняя)
3. Легко могу послать
sendmessage(lhwnd,WM_CLOSE,0,0)
- опять паника, потому что появляется Сохранить Да Нет в корявом (или вообще невидимом файле)
4. Никак не могу убить этот процесс по HWND
Пытаюсь делать так:
LPARAMETERS lhwnd  
  DECLARE integer TerminateProcess IN WIN32API integer, integer  
  DECLARE integer OpenProcess IN WIN32API integer, integer, integer  
  DECLARE integer CloseHandle IN WIN32API integer  
  DECLARE integer GetWindowThreadProcessId IN WIN32API integer, integer @  
  LOCAL hProcess, pid  
  GetWindowThreadProcessId(lhwnd, @PID);  
  hProcess=OpenProcess(1,1,pid)  
  TerminateProcess(hProcess,0)  
  CloseHandle(hProcess)
и получаю ошибку "Syntax error" в строке GetWindowThreadProcessId(lhwnd, @PID);
???



Исправлено: Sandwich, 17.09.21 00:30
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
PuMa

Сообщений: 141
Откуда: Комсомольск-на-А
Дата: 17.09.21 02:04:25
Проще всего, наверное, поместить процесс заполнения в TRY и в его секции CATCH выдать пользователю сообщение об ошибке и корректно закрыть Excel
m.loExcel.DisplayAlerts = .f.
m.loExcel.Quit()
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Crispy

Сообщений: 18571
Дата: 17.09.21 07:59:46
Sandwich
Никак не могу убить этот процесс по HWND

Можно прибивать по имени процесса через скрипты, обычно без проблем.
Типа так:
  
  cNameProcess = "excel.exe"  
  WshShell = CreateObject("WScript.Shell")  
  WshShell.Run("taskkill /IM " + cNameProcess, 0)
В офисных процессах еще, сколько помню, иногда вроде висело имя самого документа. Ну это глянуть просто надо, что там висит при его открытии.


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
ssa

Сообщений: 12739
Откуда: Москва
Дата: 17.09.21 08:49:16
Sandwich
Программно создаю (точнее заполняю готовую форму файла Excel) товарную накладную.
Методика: в папке с формами хранится Excel шаблон, программа копирует его в tmp-папку с tmp-именем, открывает эту копию и заполняет.
То есть "стандартный" закат солнца вручную. Хотя есть не менее стандартные и давно встроенные в сами офисные пакеты методы работы с шаблонами. Но подавляющее большинство народу таки предпочитает сколхозить что-нить свое.
К тому же уже есть и способы создания Excel файлов без использования Excel.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 17.09.21 08:59:58
ssa
К тому же уже есть и способы создания Excel файлов без использования Excel.
Просто программа рождена еще в самом начале этого века. Ну очень не хочется переделывать.
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Равиль

Сообщений: 6401
Откуда: Уфа
Дата: 17.09.21 10:03:52
Заброшенные при сбоях Excel-процессы - явление довольно частое, но тут не понятно почему возникает ошибка, если шаблон копируется с уникальным именем :
Sandwich
... Excel-процесс с tmp-именем остаётся "висеть" невидимым и при следующей попытке копирования шаблона в tmp-папку с tmp-именем возникает ошибка. Программа выводит соответствующее сообщение ...

Может кусочек кода этого копирования и открытия покажете ?


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 17.09.21 10:21:29
Равиль
Заброшенные при сбоях Excel-процессы - явление довольно частое, но тут не понятно почему возникает ошибка, если шаблон копируется с уникальным именем :
Sandwich
... Excel-процесс с tmp-именем остаётся "висеть" невидимым и при следующей попытке копирования шаблона в tmp-папку с tmp-именем возникает ошибка. Программа выводит соответствующее сообщение ...

Может кусочек кода этого копирования и открытия покажете ?
Имя файла не уникально, оно содержит номер документа
  
  file_name = 'счет_'+alltrim(str(doc.nomer))+'.xlsx'  
  newfile='Общая папка\Документы\Счета\'+file_name   
  ON ERROR copy_error=.t.  
  copy file &form_dir\&form_file to (newfile)  
  ON ERROR   
  IF copy_error  
 	* здесь надо убить процесс и скопировать снова  
  ENDIF   
  LOCAL loExcel as Excel.Application  
  loExcel=CREATEOBJECT('Excel.Application')  
  LOCAL loBook as Excel.Workbook  
  loBook = m.loExcel.workbooks.open(newfile)
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Равиль

Сообщений: 6401
Откуда: Уфа
Дата: 17.09.21 10:38:59
Sandwich
...
Имя файла не уникально, оно содержит номер документа
[code]
file_name = 'счет_'+alltrim(str(doc.nomer))+'.xlsx'
newfile='Общая папка\Документы\Счета\'+file_name
...

Так и думал, это приведет ко многим проблемам, например если 2 пользователя захотят одновременно создать один и тот же документ ?
Добавьте хотя бы sys(2015) к имени файла и не придется ловить процессы и убивать
file_name = 'счет_'+alltrim(str(doc.nomer))+sys(2015)+'.xlsx'
Или работайте с файлом во временной папке и уже потом сохраняйте его в общую.


------------------
Тяжело согнать курсором муху с монитора ...
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
AleksM

Сообщений: 17803
Дата: 17.09.21 10:42:05
Работать нужно через шаблоны, в полном понимании этого слова в парадигме офиса.
Обсуждение по данному поводу можно найти через поиск.


------------------
Лучше переесть, чем недоспать.
Не спеши, а то успеешь.
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 17.09.21 11:13:16
Друзья, я в первом посте написал
Sandwich
Естественно методика не выдерживает критики
Ваши замечания, безусловно, по делу.
Но ведь вопрос стоит более широко: я не умею убивать процессы (и не важно Excel или нет, формы, парадигмы, юзеры, разделения полномочий и пр.)

Crispy
cNameProcess = "excel.exe"
WshShell = CreateObject("WScript.Shell")
WshShell.Run("taskkill /IM " + cNameProcess, 0)
убивает все Открытые Excel окна, а скрытый процесс продолжает висеть
Пока ковыряю в эту сторону.
Если ставлю
cNameProcess = "имя_окна_полученное_по_его_хэндлу"
тоже без результата
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
ssa

Сообщений: 12739
Откуда: Москва
Дата: 17.09.21 12:18:20
Sandwich
Но ведь вопрос стоит более широко: я не умею убивать процессы (и не важно Excel или нет, формы, парадигмы, юзеры, разделения полномочий и пр.)
Это не умеют делать подавляющее большинство программистов. Ибо нефиг. Это лечение последствий, а не причин.
Sandwich
Просто программа рождена еще в самом начале этого века. Ну очень не хочется переделывать.
Но именно переделыванием кое-кто таки сейчас и занимается. К тому же, рекомендуемая переделка не такая уж и большая и сложная.

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Владимир Максимов

Сообщений: 13911
Откуда: Москва
Дата: 17.09.21 12:20:40
Бороться надо не с последствиями, а с причиной

У Вас произошел сбой при выполнении некой операции в FoxPro. Для перехвата таких ситуаций есть конструкция TRY...CATCH


  
  loExcel = createobject("excel.application")    
    
  TRY  
    * Операция с Excel, которая может завершиться ошибкой  
  CATCH  
    * Если попали сюда, то произошла ошибка  
    * Штатное закрытие экземпляра Excel  
     loExcel.DisplayAlerts = .F.  
     loExcel.saved = .T.  
     loExcel.Workbooks.Close()  
     loExcel.quit()  
  ENDTRY
Ratings: 0 negative/1 positive

Re: Убить насмерть Excel процесс
Crispy

Сообщений: 18571
Дата: 17.09.21 14:25:27
Sandwich
убивает все Открытые Excel окна, а скрытый процесс продолжает висеть

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

В принципе же - приведенные здесь советы по переделке программы все же более корректны могли бы оказаться.


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
of63

Сообщений: 21729
Откуда: Н.Новгород
Дата: 17.09.21 16:20:41
Вот тут пишут как получить PID потока, и как его убить, на примере Excel
stackoverflow.com

везде пишут
axforum.info



Исправлено: of63, 17.09.21 16:23
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 17.09.21 20:58:29
Всем большое спасибо за ответы.
Crispy
приведенные здесь советы по переделке программы все же более корректны могли бы оказаться.
Не подумайте, что я уперся и не слушаю:
я сделал и то, и это:
1. Разобрался и сделал функцию, которая при необходимости может убить любой процесс (видимый или не видимый)
2. Переделал функционал, используя TRY...CATCH
Еще раз спасибо
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Igor Korolyov

Сообщений: 34290
Дата: 19.09.21 13:37:03
Убивать процесс нехорошо уже хотя бы потому что потом, при очередном старте экселя он может предложить "восстановить файл после сбоя".

"Развести" генерируемые файлы с одним и тем же именем можно, создавая их в разных подпапках %TEMP% - имена подпапок уже сделать не одинаковыми (случайными, или последовательными типа 1,2,3...)

Если вдруг штатного функционала перехвата и обработки ошибок (try ... catch, on error ...) окажется недостаточно (это возможно, если ошибка будет связана с крахом фоксового процесса - а эксель будет вполне себе продолжать работать), то можно попытаться "подключиться" к уже запущенному эксель-процессу, используя GETOBJECT(,"Excel.Application") и как-то "разрулить" ситуацию - например найти и закрыть недоформированный документ. Главное держать в уме, что таким образом можно запросто вломиться в интерактивный экселевский процесс запущенный самим пользователем (а что-то делать с его документами не есть хорошо).

Как общая рекомендация к програмной работе с экселем - формировать документ (заполнять шаблон) стоит в отдельной, независимой копии экселя (созданной по CreateObject("Excel.Application") и по возможности максимально "изолированной" от взаимодействия с пользователем - подавить все предупреждения, заблокировать "внешние запросы", НЕ делать окно видимым). По завершению формирования документа сохранить его в нужное место под нужным именем и завершить рабочий экселевский процесс. Затем "открыть" на просмотр готовый документ при помощи ShellExecute() или иным способом - уже в "обычной" копии экселя, возможно запущенной ранее самим пользователем - без контроля над тем что там будет пользователь с этим документом делать (это тоже не всегда возможно, но если нет требований "следить" за юзером и тем что он с документом делает, то будет норм).


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: Убить насмерть Excel процесс
Sandwich
Автор

Сообщений: 122
Дата: 19.09.21 13:51:30
Igor Korolyov
Убивать процесс нехорошо уже хотя бы потому что потом, при очередном старте экселя он может предложить "восстановить файл после сбоя".
Он и предлагает, доработаю.
Igor Korolyov
По завершению формирования документа сохранить его в нужное место под нужным именем и завершить рабочий экселевский процесс.
А если в нужном месте с нужным именем есть и открыт предыдущий файл, да еще и в процессе корректировки данных? тут уже без юзера не обойтись.
Пишу и сам думаю: а я ведь до начала формирования проверяю такое событие и активирую такое окно.
Спасибо за советы
Ratings: 0 negative/0 positive



Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 9 (Гостей: 9)

© 2000-2021 Fox Club 
Яндекс.Метрика