Переключение на Главную Страницу Страницы: 1 2 [3]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля (число прочтений - 14221 )
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #30 - 25. Ноября 2009 :: 12:26
Печать  
Вот... Тебе удовольствие, а мне пришлось в коде целых 42 символа написать!
Улыбка
  

FormEx developer
Наверх
www  
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #31 - 25. Ноября 2009 :: 16:50
Печать  
Практически закончил работу над процедурой.
Уперся в последний штрих. Когда хэши не совпадают и нужно открываемый файл обработки заменить эталонным.

Подскажите, пожалуйста, как можно закрыть файл открываемой внешней обработки?

Что я хочу:
Если хэш открываемой обработки не соответствует эталону (или обновленному/измененному), то открываемый - закрыть, переписать его новым из MySQL, а пользователю открыть новый-эталонный файл обработки. И даже догадываться об этом он не должен.
Два в одном, так сказать, и оперативное обновление и защита.

Заранее спасибо!

P.S.: если АЛьФ смог получить хэш у залоченного файла, то и закрыть его, ИМХО, для него не проблема Улыбка
  
Наверх
IP записан
 
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #32 - 25. Ноября 2009 :: 21:19
Печать  
Не. Я могу только посоветовать как отменить запуск (статус возврата в ноль скинуть при загрузке внешнего отчета). А вот как потом записать другой на его место и запустить его... ИМХО только через обработку ожидания что-то мутить и ждать пока файл освободится.
  

FormEx developer
Наверх
www  
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #33 - 26. Ноября 2009 :: 11:18
Печать  
АЛьФ писал(а) 25. Ноября 2009 :: 21:19:
Не. Я могу только посоветовать как отменить запуск (статус возврата в ноль скинуть при загрузке внешнего отчета). А вот как потом записать другой на его место и запустить его... ИМХО только через обработку ожидания что-то мутить и ждать пока файл освободится.

Можно еще через ВнешнееСобытие() попробовать доступ получить
  
Наверх
ICQ  
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #34 - 26. Ноября 2009 :: 14:36
Печать  
АЛьФ писал(а) 25. Ноября 2009 :: 21:19:
Не. Я могу только посоветовать как отменить запуск (статус возврата в ноль скинуть при загрузке внешнего отчета). А вот как потом записать другой на его место и запустить его... ИМХО только через обработку ожидания что-то мутить и ждать пока файл освободится.

Что-то СтатусВозврата(0) не снимает блокировку файла.
Делал через обработку ожидания с интервалом 100 мс и 30 сек. Результат один - файл залочен.

Какие еще есть идеи?
  
Наверх
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #35 - 26. Ноября 2009 :: 14:37
Печать  
Salimbek писал(а) 26. Ноября 2009 :: 11:18:
Можно еще через ВнешнееСобытие() попробовать доступ получить

А это как? По-подробней, пожалуйста.
  
Наверх
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #36 - 26. Ноября 2009 :: 14:52
Печать  
simply писал(а) 26. Ноября 2009 :: 14:36:
Какие еще есть идеи?

Если каталог для обработок сделать подключаемым сетевым, и все ert-ки открывать только через сетевой путь (даже на локальном компьютере), то в любом месте при помощи "net use" можно разблокировать файл прибив сетевой диск. Потом можно подключить его обратно и перезаписать.

Но докатиться до такого извращения не хоца ...
  
Наверх
IP записан
 
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #37 - 27. Ноября 2009 :: 06:36
Печать  
simply писал(а) 26. Ноября 2009 :: 14:36:
Что-то СтатусВозврата(0) не снимает блокировку файла.

И не должен. Он должен только прерывать текущий запуск внешнего отчета.
  

FormEx developer
Наверх
www  
IP записан
 
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #38 - 27. Ноября 2009 :: 06:56
Печать  
simply писал(а) 26. Ноября 2009 :: 14:37:
Salimbek писал(а) 26. Ноября 2009 :: 11:18:
Можно еще через ВнешнееСобытие() попробовать доступ получить

А это как? По-подробней, пожалуйста.

В глобальнике что-то типа такого:
Код
Выбрать все
Процедура ОбработкаВнешнегоСобытия(Источник,Событие,Данные)
	Если Источник = "Отчеты" Тогда
		Если Событие = "ЗаменаОтчета" Тогда
			текДанные = СтрЗаменить(СтрЗаменить(Данные,"/",РазделительСтрок),"\",РазделительСтрок);
			ИмяФайла = СтрПолучитьСтроку(текДанные,СтрКоличествоСтрок(текДанные));
			ИмяКаталога = Лев(Данные,СтрДлина(Данные) - СтрДлина(ИмяФайла));
			ФС.ПереименоватьФайл(Данные,ИмяКаталога + "11.ert",1);
			ФС.КопироватьФайл(ИмяКаталога + "2.ert",Данные,1);
			ОткрытьФорму("Отчет",,Данные);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ПриЗагрузкеВнешнегоОтчета(Путь)
	Если Сервис.ПолучитьХэшМД5(Путь,1) = "1575D21A7BB0EE24D8EA5641E7232CB0" Тогда
		Сервис.ВнешнееСобытие("Отчеты","ЗаменаОтчета",Путь);
		СтатусВозврата(0);
	КонецЕсли;
КонецПроцедуры
 

  

FormEx developer
Наверх
www  
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #39 - 27. Ноября 2009 :: 07:43
Печать  
Большое спасибо!

P.S.: Интересно, чего в этой процедуре волшебного, что у нее больше шансов получить доступ к залоченному файлу?
P.P.S.: Классный способ встроенным языком 1С получить имя файла и его путь!  Очень довольный  Я до такого изящного решения не додумался и не стал мучаться:
Код
Выбрать все
	ФСО=СоздатьОбъект("Scripting.FileSystemObject");
	ИмяФайла=ФСО.GetFile(ФайлОтчета).Name;
	ПутьФайла=ФСО.GetParentFolderName(ФайлОтчета)+"\";
	ФСО=Пусто;  

  
Наверх
IP записан
 
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #40 - 27. Ноября 2009 :: 07:49
Печать  
simply писал(а) 27. Ноября 2009 :: 07:43:
P.S.: Интересно, чего в этой процедуре волшебного, что у нее больше шансов получить доступ к залоченному файлу?

Волшебного в ней то, что она создает асинхронное событие, которое 1С отрабатывает уже после завершения текущей операции, т.е. после освобождения файла.
  

FormEx developer
Наверх
www  
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #41 - 27. Ноября 2009 :: 08:07
Печать  
АЛьФ писал(а) 27. Ноября 2009 :: 07:49:
simply писал(а) 27. Ноября 2009 :: 07:43:
P.S.: Интересно, чего в этой процедуре волшебного, что у нее больше шансов получить доступ к залоченному файлу?

Волшебного в ней то, что она создает асинхронное событие, которое 1С отрабатывает уже после завершения текущей операции, т.е. после освобождения файла.

Еще раз - большое спасибо! Не знал  Улыбка
  
Наверх
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #42 - 27. Ноября 2009 :: 11:45
Печать  
Все получилось без ОбработкиВнешнегоСобытия(), через обработку ожидания.
Громоздко, но это из-за контролей.
Код
Выбрать все
Перем спФайлыОтчетов;	 // : СписокЗначений. Файлы отчетов для перезаписи. <Значение> - новый файл-источник с полным путем, <Строка> - полное имя старого файла отчета. (Simply 26.11.2009)
Перем КвоОшибокТаймер3;	 // : Число. Мера против зацикливания для <Таймер3> (Simply 26.11.2009)
...
//-----------------------------------------------
Процедура ПриНачалеРаботыСистемы()
...
	Таймер3.ЗадатьОбработчикВГлобальномМодуле("ОбновитьВнешнююОбработку");
	спФайлыОтчетов=СоздатьОбъект("СписокЗначений");	// : Список файлов внешних отчетов перезаписи для <Таймер3>
...
КонецПроцедуры // ПриНачалеРаботыСистемы 


Код
Выбрать все
//================================================== FormEx
Процедура ПриЗагрузкеВнешнегоОтчета(ФайлОтчета)
	ИмяПроцедуры="ПриЗагрузкеВнешнегоОтчета";
	флПродолжитьВыполнение=1; // : Число. Флаг отсутсвия ошибок
	// Этап 1. Получение данных о файле отчета
	Попытка
		ФСО=СоздатьОбъект("Scripting.FileSystemObject");
		ИмяФайла=ФСО.GetFile(ФайлОтчета).Name;
		ФСО=Пусто;
		Если ПустаяСтрока(ИмяФайла)=1 Тогда
			глИнформация("# Ошибка получения имени файла внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
			флПродолжитьВыполнение=0;
		КонецЕсли;
		Если флПродолжитьВыполнение=1 Тогда
			ХэшФайла=глСервис.ПолучитьХэшМД5(ФайлОтчета,1);
			Если (ПустаяСтрока(ХэшФайла)=1) ИЛИ (СтрДлина(ХэшФайла)<32) Тогда
				глИнформация("# Ошибка! Нет хэш-кода внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
				флПродолжитьВыполнение=0;
			ИначеЕсли ХэшФайла="00000000000000000000000000000000" Тогда
				глИнформация("# Ошибка! Файл внешнего отчета '"+ФайлОтчета+"' заблокирован!","Процедура",ИмяПроцедуры);
				флПродолжитьВыполнение=0;
			КонецЕсли;
		КонецЕсли;
	Исключение
		глИнформация("# Ошибка получения данных о файле внешнего отчета "+ФайлОтчета+" = "+ОписаниеОшибки(),"Процедура",ИмяПроцедуры);
		флПродолжитьВыполнение=0;
	КонецПопытки;
	// Этап 2. Сверка с эталоном. MySQL возвращает: 'ok' (все в порядке), 'no' (разный хэш), 'nf' (нет такого файла)
	Если флПродолжитьВыполнение=1 Тогда
		MySQLПолучить("CALL files.checkert('"+ИмяФайла+"','"+ХэшФайла+"');"); //Rst.Open("CALL files.checkert('"+ИмяФайла+"','"+МдФайла+"');",Conn,0,1);
		Попытка
			Если Rst.EOF()=0 Тогда
				Если Rst.RecordCount()>0 Тогда
					Результат=СокрЛП(Rst.Fields("result_").Value);
					Если ПустоеЗначение(Результат)=1 Тогда
						глИнформация("# Ошибка! Нет значения 'result_' для внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
					Иначе
						Если Результат="ok" Тогда
						Иначе
							СтатусВозврата(0);
							КвоЗапусков=0;
							Если Результат="nf" Тогда
								глИнформация("# Ошибка! Запущен неизвестный файл отчета - '"+ФайлОтчета+"'!","Процедура",ИмяПроцедуры);
							Иначе
								НовФайл=Rst.Fields("file_");
								Если ПустоеЗначение(НовФайл)=1 Тогда
									глИнформация("# Ошибка! Нет значения 'file_' для внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
								Иначе
									Stream=СоздатьОбъект("ADODB.Stream");
									Stream.Mode=3;
									Stream.Type=1;
									Stream.Open();
									Stream.Write(НовФайл);
									Stream.SaveToFile(КаталогВременныхФайлов()+ИмяФайла,2);
									Stream=Пусто;
									Если ФС.СуществуетФайл(КаталогВременныхФайлов()+ИмяФайла)=0 Тогда
										глИнформация("# Ошибка записи на диск эталона внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
									Иначе
										флДобавитьВСписок=1;
										Если Таймер3.Запущен=1 Тогда
											Если спФайлыОтчетов.НайтиЗначение(КаталогВременныхФайлов()+ИмяФайла)>0 Тогда
												глИнформация("# Файл внешнего отчета '"+КаталогВременныхФайлов()+ИмяФайла+"' уже ожидает перезаписи!","Процедура",ИмяПроцедуры);
												флДобавитьВСписок=0;
											КонецЕсли;
										Иначе
											Таймер3.Запустить(100);
										КонецЕсли;
										Если флДобавитьВСписок=1 Тогда
											спФайлыОтчетов.ДобавитьЗначение(КаталогВременныхФайлов()+ИмяФайла,ФайлОтчета);
										КонецЕсли;
									КонецЕсли;
								КонецЕсли;
							КонецЕсли;
						КонецЕсли;
					КонецЕсли;
				Иначе
					глИнформация("# Ошибка! Нет данных по проверке внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
				КонецЕсли;
			КонецЕсли;
		Исключение
			глИнформация("# Ошибка выполнения хранимой процедуры по внешнему отчету "+ФайлОтчета+" = "+ОписаниеОшибки(),"Процедура",ИмяПроцедуры);
		КонецПопытки;
		Попытка Rst.Close(); Исключение КонецПопытки;
	КонецЕсли;
КонецПроцедуры // ПриЗагрузкеВнешнегоОтчета 

  
Наверх
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #43 - 27. Ноября 2009 :: 11:46
Печать  
... продолжение
Код
Выбрать все
//================================================== <Таймер3>
Процедура ОбновитьВнешнююОбработку()
	Если спФайлыОтчетов.РазмерСписка()>0 Тогда
		ИмяПроцедуры="ОбновитьВнешнююОбработку";
		Результат=0; Ошб=0;
		Для нс=1 По спФайлыОтчетов.РазмерСписка() Цикл
			ФайлОтчета="";
			Источник=спФайлыОтчетов.ПолучитьЗначение(нс,ФайлОтчета);
			Если ФС.СуществуетФайл(Источник)=1 Тогда
				Попытка
					ФС.УдалитьФайл(ФайлОтчета);
					ФС.КопироватьФайл(Источник,ФайлОтчета,0);
					Если глСервис.ПолучитьХэшМД5(Источник,1)=глСервис.ПолучитьХэшМД5(ФайлОтчета,1) Тогда
						глИнформация("# Внешний отчет "+Источник+" успешно обновлен!","Процедура",ИмяПроцедуры);
					Иначе
						а=1/0;
					КонецЕсли;
					Результат=Результат+1;
				Исключение
					КвоОшибокТаймер3=КвоОшибокТаймер3+1;
					глИнформация("# Ошибка перезаписи внешнего отчета "+Источник+" попытка "+КвоОшибокТаймер3,"Процедура",ИмяПроцедуры);
					Если КвоОшибокТаймер3>3 Тогда
						Таймер3.Остановить();
						глИнформация("# Ошибка! Прекащены попытки перезаписи внешнего отчета "+ФайлОтчета,"Процедура",ИмяПроцедуры);
						Прервать;
					КонецЕсли;
				КонецПопытки;
			Иначе
				глИнформация("# Нет файла-источника '"+Источник+"' для перезаписи старого файла "+ФайлОтчета+"!","Процедура",ИмяПроцедуры);
				Результат=Результат+1; // обновлять нечего, оставляем до следующего раза
				Ошб=Ошб+1;
			КонецЕсли;
		КонецЦикла;
		ФСО=Пусто;
		Если Результат=спФайлыОтчетов.РазмерСписка() Тогда
			Таймер3.Остановить();
			Если (спФайлыОтчетов.РазмерСписка()=1) И (Ошб=0) Тогда
				ФайлОтчета="";
				спФайлыОтчетов.ПолучитьЗначение(1,ФайлОтчета);
				Если ОткрытьФорму("Отчет",,ФайлОтчета)=1 Тогда
					глИнформация("# Внешний отчет '"+ФайлОтчета+"' открыт успешно!","Процедура",ИмяПроцедуры);
				Иначе
					глИнформация("# Ошибка открытия внешнего отчета "+ФайлОтчета+"!","Процедура",ИмяПроцедуры);
				КонецЕсли;
			КонецЕсли;
			спФайлыОтчетов.УдалитьВсе();
		КонецЕсли;
	КонецЕсли;
	Состояние("Проверяются файлы");
КонецПроцедуры // ОбновитьВнешнююОбработку
 


Примечания:
1. Процедуру глИнформация использую для отладки новых участков. Если в начале стоит "# Ошибка", то уведомление немедленно отсылается мне.
2. Файлы для перезаписи храню в списке на всякий случай. Маловероятно, что пользователь успеет за 100 мс запустить более одной, но ...

Огромное спасибо всем за помощь!  Улыбка
Особенно - АЛьФу (и за оперативный новый релиз Подмигивание)
  
Наверх
IP записан
 
simply
God Member
*****
Отсутствует


Мечта: избавиться от 1С

Сообщений: 573
Местоположение: Киев
Зарегистрирован: 31. Декабря 2008
Пол: Мужской
Re: Метод "ПолучитьХэшМД5()" возвращает тридцать два нуля
Ответ #44 - 18. Декабря 2009 :: 15:03
Печать  
АЛьФ писал(а) 27. Ноября 2009 :: 06:56:
В глобальнике что-то типа такого:
Код
Выбрать все
Процедура ОбработкаВнешнегоСобытия(Источник,Событие,Данные)
	Если Источник = "Отчеты" Тогда
		Если Событие = "ЗаменаОтчета" Тогда
			текДанные = СтрЗаменить(СтрЗаменить(Данные,"/",РазделительСтрок),"\",РазделительСтрок);
			ИмяФайла = СтрПолучитьСтроку(текДанные,СтрКоличествоСтрок(текДанные));
			ИмяКаталога = Лев(Данные,СтрДлина(Данные) - СтрДлина(ИмяФайла));
			ФС.ПереименоватьФайл(Данные,ИмяКаталога + "11.ert",1);
			ФС.КопироватьФайл(ИмяКаталога + "2.ert",Данные,1);
			ОткрытьФорму("Отчет",,Данные);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ПриЗагрузкеВнешнегоОтчета(Путь)
	Если Сервис.ПолучитьХэшМД5(Путь,1) = "1575D21A7BB0EE24D8EA5641E7232CB0" Тогда
		Сервис.ВнешнееСобытие("Отчеты","ЗаменаОтчета",Путь);
		СтатусВозврата(0);
	КонецЕсли;
КонецПроцедуры
 


Спасибо еще раз! Улыбка

Спустя время пришел к выводу что через "ОбработкуВнешнегоСобытия()" проще, надежней и кода раза в три меньше.
  
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: 1 2 [3] 
ОтправитьПечать