Что нового

[Сеть, интернет] Автоматизация загрузки файла с ФТП сервера и дальнейшая работа с ним

Alsagas

Новичок
Сообщения
15
Репутация
0
Версия AutoIt: 3.3.14.2

Описание: Добрый день, уважаемые специалисты. Помогите, пожалуйста с написанием скрипта для автоматической загрузки рекламного ролика с фпт сервера и его последующего запуска.

Подробное описание:
На компе есть локальная папка D:\Реклама, там лежит файл файл.pps, который круглосуточно крутится на рекламных мониторах у нас на предприятии. Раз в месяц происходит замена рекламного файла на новый, который выкладывается на ФТп сервер, который находится в головном офисе. Тут и все, в принципе, но есть одна заковыка, файл просто так не перезаписать, так как он в это время работает и система его зашищает от перезаписи. Приходится заходить удаленно, завершать процесс и только потом заливать этот файл и запускать его. Ярлык файла лежит в автозагрузке для того, чтобы при рестарте компа он запускался автоматом.

Что бы хотелось увидеть:
1. Ежедневный заход на фтп сервер в определенное время с проверкой не появился ли новый файл с измененной датой или размером.
2. Если файл новый есть, то остановить процесс powerpnt.exe
3. Скачать новый файл с заменой старого (ну или с удалением старого, как удобнее.) (Название файла всегда одно и то же)
4. Дождаться окончания закачки.
5. Запустить файл.

Примечания: Если можно, то настройки вынести в .ini файл, так как директории и диски, и названия файлов в разных филиалах могут быть разными.


Заранее благодарен.
 

hedji

Продвинутый
Сообщения
409
Репутация
94
По опыту лучше не вешать скрипт в бесконечный цикл с проверкой времени, а сделать запланированное задание в планировщике винды.
Презенташку на ftp не нашел, сделал на примере pdf файла.
Код:
$url = IniRead(@ScriptDir & "\test.ini", "Settings", "url", "not_found") ;читаем url что качать
$old_file = IniRead(@ScriptDir & "\test.ini", "Settings", "old_file", "not_found") ;читаем где лежит старый файл
If FileExists(@ScriptDir & "\test.pdf") Then
	FileDelete(@ScriptDir & "\test.pdf")
EndIf
InetGet($url, @ScriptDir & "\test.pdf", 1, 0)
$new_file_size = FileGetSize(@ScriptDir & "\test.pdf")
$old_file_size = FileGetSize($old_file)
If $new_file_size <> $old_file_size Then
	ProcessClose("powerpnt.exe")
	FileCopy(@ScriptDir & "\test.pdf", $old_file, 1)
	Run($old_file)
EndIf


содержание ini-файла
Код:
[settings]
url=http://ftp.dlink.ru/pub/Router/DIR-300/Data_sh/DS_DIR-300_RUS_02.pdf
old_file=D:\Scripts\test\test_old.pdf
 
Автор
A

Alsagas

Новичок
Сообщения
15
Репутация
0
Спасибо большое, но нужен заход через фтп соединение с авторизацией. Понятное дело, что зацикливать не стоит и все будет делаться через планировщик.
 

sergioz

Знающий
Сообщения
39
Репутация
5
Код:
#include <Crypt.au3>
$SourceFile = IniRead(@ScriptDir & "\test.ini", "Settings", "url", "not_found") ;читаем url что качать
$DestFile = IniRead(@ScriptDir & "\test.ini", "Settings", "old_file", "not_found") ;читаем где лежит старый файл


_Ftp_Get_File($SourceFile,$DestFile&"_new");через зп вписать логин и пасс

if (_Crypt_HashFile($DestFile, $CALG_MD5) <> _Crypt_HashFile($DestFile&"_new", $CALG_MD5)) then ; если файлы разные то обновляемся
	RunWait(@ComSpec & ' /c TASKKILL /FI "IMAGENAME eq *powerpnt*" /F /T' , @SW_HIDE)
	FileDelete($DestFile)
	FileMove($DestFile&"_new",$DestFile,1)
	Run($DestFile)
EndIf


Func _Ftp_Get_File($S_File, $D_File, $user='anonymous', $pass='anonymous',$delete=False)
; Выделяем имя файла
Local $S_File_name = $S_File
Local $S_SrvName = $S_File
Local $strSwitch = True

While $strSwitch
	if StringInStr ( $S_File_name, '/' ) then
		$S_File_name = StringTrimLeft ( $S_File_name, StringInStr ( $S_File_name, '/' ) )
	Else
		$strSwitch = False
	EndIf
WEnd
; Выделяем имя файла
	if StringLeft ($S_SrvName,6) = 'ftp://' Then
		$S_SrvName = StringTrimLeft ( $S_SrvName, 6  )
		$S_File = StringTrimLeft ( $S_File , 6  )
	EndIf
	$S_SrvName = StringTrimRight ( $S_SrvName, StringLen($S_SrvName) - StringInStr ( $S_SrvName, '/' ) +1 );выделяем имя сервера
	$S_File = StringTrimLeft($S_File , StringLen($S_SrvName))
	$S_File = StringTrimRight($S_File, StringLen($S_File_name));выделяем путь ФТП
	$Open = _FTP_Open('MyFTP Control')
	$Conn = _FTP_Connect($Open, $S_SrvName, $user, $pass)
	_FTP_DirSetCurrent($Conn, $S_File)
	_FTP_FileGet ($Conn, $S_File_name, $D_File)
	if $delete then _FTP_FileDelete($Conn, $S_File_name)
	_FTP_Close($Open)

EndFunc



надо будет с путями файлов поиграться
 

sergioz

Знающий
Сообщения
39
Репутация
5
Alsagas сказал(а):
выдает

: error: _FTP_Open(): undefined function.

Забыл еще добавить что порт на фтп не стандартный.

Код:
#include <FTPEx.au3> ; забыл про него

в либе про настройку порта ничего не нашел
по этому используйте работу с TCP напрямую

могу рекомендовать встроенный консольный ftp.exe - к нему можно в текстовом файле скрипты писать

Код:
cmd -> ftp /?
 -s:имя_файла    Задание текстового файла, содержащего команды FTP, которые
                 будут выполняться автоматически при запуске FTP.
 
Автор
A

Alsagas

Новичок
Сообщения
15
Репутация
0
Давайте упростим задачу, благо сейчас достаточно софта для синхронизации файлов:
Есть папка D:\Reklama\moscow.pps и тут же D:\Reklama\Temp\moscow.pps
В корне папка reklama лежит файл, который на данный момент времени запущен на компе и проигрывает ролик.
В папке reklama\Temp лежит такой же файл, но более новый, скачанный с фтп.
Нужно сравнить файл в обеих папках и, если файл в папке temp окажется более новым, то остановить процесс powerpnt.exe, переписать новый файл на место старого (То есть из папки D:\Reklama\Temp в папку D:\Reklama , и запустить этот файл.
Я думаю это будет гораздо проще.
Заранее благодарен.
 

hedji

Продвинутый
Сообщения
409
Репутация
94
Код:
$new_file_size = FileGetSize("D:\Reklama\Temp\moscow.pps")
$old_file_size = FileGetSize("D:\Reklama\moscow.pps")
If $new_file_size <> $old_file_size Then
    ProcessClose("powerpnt.exe")
    FileCopy("D:\Reklama\Temp\moscow.pps", "D:\Reklama\moscow.pps", 1)
    Run("D:\Reklama\moscow.pps")
EndIf
 
Автор
A

Alsagas

Новичок
Сообщения
15
Репутация
0
Спасибо. Последний вариант заработал нормально, только пришлось вместо Run использовать ShellExecute при запуске файла.
 
Автор
A

Alsagas

Новичок
Сообщения
15
Репутация
0
Уважаемый hedji, а нельзя ли сюда еще и инишник прикрутить? Просто пути могут немного отличаться и мне чтобы не компилить скрипт под каждый комп отдельно, желательно бы инишку сделать. В ней особо ничего не надо, только чтобы можно было вносить пусть к старому и новому файлам.
Спасибо.
 

hedji

Продвинутый
Сообщения
409
Репутация
94
Код:
$old_file = IniRead(@ScriptDir & "\test.ini", "Settings", "old_file", "not_found")
$new_file = IniRead(@ScriptDir & "\test.ini", "Settings", "new_file", "not_found")
if $old_file = "not_found" Or $new_file = "not_found" Then
	MsgBox(0, "", "Не удалось прочитать файл test.ini")
	Exit
EndIf
$new_file_size = FileGetSize($new_file)
$old_file_size = FileGetSize($old_file)
If $new_file_size <> $old_file_size Then
    ProcessClose("powerpnt.exe")
    FileCopy($new_file, $old_file, 1)
    ShellExecute($old_file)
EndIf


в ini-файле:
Код:
[settings]
old_file=D:\Reklama\moscow.pps
new_file=D:\Reklama\Temp\moscow.pps
 

webresurs

Новичок
Сообщения
1
Репутация
0
тут под правил ваш прим и хочется добавить прогресс бар..

можете добавить прогресс бар при загрузке с фтп ?

Код:
#include <Crypt.au3>
#include <FTPEx.au3> 
#include <MsgBoxConstants.au3>

$SourceFile = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "url", "not_found") ;читаем url что качать
$DestFile = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "old_file", "not_found") ;читаем где лежит старый файл
$DestFileTemp = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "old_file_temp", "not_found") ;читаем где лежит временный файл

if $SourceFile = "not_found" Or $DestFile = "not_found" Then
    MsgBox(0, "", "Не удалось прочитать файл настроек updateop.ini")
    Exit
EndIf

_Ftp_Get_File($SourceFile,$DestFile&"_new");загрузка файла с фтп с новым расширением для сравнения

if (_Crypt_HashFile($DestFile, $CALG_MD5) <> _Crypt_HashFile($DestFile&"_new", $CALG_MD5)) then ; если файлы разные то обновляемся
    ;RunWait(@ComSpec & ' /c TASKKILL /FI "IMAGENAME eq *msaccess*" /F /T' , @SW_HIDE)
	MsgBox(4096, "Проверка", "Идет обновление..", 10)
	ProcessClose("msaccess.exe")
	Sleep(10000) ;  Приостановка скрипта на 1 секунду -1000
	FileDelete($DestFileTemp)
    FileDelete($DestFile)
    FileMove($DestFile&"_new",$DestFile,1)
    ShellExecute($DestFile) ;Run($DestFile)
   Else
    MsgBox(4096, "Проверка на обновление", "Обновлений нет..", 10)
	    ShellExecute($DestFile) ;Run($DestFile)
EndIf


Func _Ftp_Get_File($S_File, $D_File, $user='anonymous', $pass='anonymous',$delete=False)
; Выделяем имя файла
Local $S_File_name = $S_File
Local $S_SrvName = $S_File
Local $strSwitch = True

While $strSwitch
    if StringInStr ( $S_File_name, '/' ) then
        $S_File_name = StringTrimLeft ( $S_File_name, StringInStr ( $S_File_name, '/' ) )
    Else
        $strSwitch = False
    EndIf
WEnd
; Выделяем имя файла
    if StringLeft ($S_SrvName,6) = 'ftp://' Then
        $S_SrvName = StringTrimLeft ( $S_SrvName, 6  )
        $S_File = StringTrimLeft ( $S_File , 6  )
    EndIf
    $S_SrvName = StringTrimRight ( $S_SrvName, StringLen($S_SrvName) - StringInStr ( $S_SrvName, '/' ) +1 );выделяем имя сервера
    $S_File = StringTrimLeft($S_File , StringLen($S_SrvName))
    $S_File = StringTrimRight($S_File, StringLen($S_File_name));выделяем путь ФТП
    $Open = _FTP_Open('MyFTP Control')
    $Conn = _FTP_Connect($Open, $S_SrvName, $user, $pass)
    _FTP_DirSetCurrent($Conn, $S_File)
    _FTP_FileGet ($Conn, $S_File_name, $D_File)
    if $delete then _FTP_FileDelete($Conn, $S_File_name)
    _FTP_Close($Open)

EndFunc



Добавлено:
Сообщение автоматически объединено:

webresurs сказал(а):
можете добавить прогресс бар при загрузке с фтп ?

нашел:

Код:
#include <Crypt.au3>
#include <FTPEx.au3> 
#include <MsgBoxConstants.au3>

;прогресс бар
Global $hCallBack = 0, $ahTimer = 0
Global $iProgress_InitSet = 0
Global $sProgress_Title = "Прогресс установки"
Global $sProgress_SubText = "Рабочий процесс: %i%%"
Global $sProgress_MainText = "Пожалуйста, подождите..."
;прогресс бар

$SourceFile = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "url", "not_found") ;читаем url что качать
$DestFile = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "old_file", "not_found") ;читаем где лежит старый файл
$DestFileTemp = IniRead(@ScriptDir & "\updaterop.ini", "Settings", "old_file_temp", "not_found") ;читаем где лежит временный файл

if $SourceFile = "not_found" Or $DestFile = "not_found" Then
    MsgBox(0, "", "Не удалось прочитать файл настроек updateop.ini")
    Exit
EndIf

_Ftp_Get_File($SourceFile,$DestFile&"_new");через зп вписать логин и пасс

if (_Crypt_HashFile($DestFile, $CALG_MD5) <> _Crypt_HashFile($DestFile&"_new", $CALG_MD5)) then ; если файлы разные то обновляемся
    ;RunWait(@ComSpec & ' /c TASKKILL /FI "IMAGENAME eq *msaccess*" /F /T' , @SW_HIDE)
	MsgBox(4096, "Проверка на обновление", "Идет обновление...Пожалуйста, подождите...", 20)
	ProcessClose("msaccess.exe")
	Sleep(10000) ;  Приостановка скрипта на 1 секунду -1000
	FileDelete($DestFileTemp)
    FileDelete($DestFile)
    FileMove($DestFile&"_new",$DestFile,1)
	  ;прогресс бар   ;Выключаем диалог прогресса
	  ProgressSet(100, "Завершено", "Полностью выполнено")
	  ProgressOff()
	  ;прогресс бар	
    ShellExecute($DestFile) ;Run($DestFile)
   Else
	  ;прогресс бар   ;Выключаем диалог прогресса
	  ProgressSet(100, "Завершено", "Полностью выполнено")
	  ProgressOff()
	  ;прогресс бар	

	  MsgBox(4096, "Проверка на обновление", "Обновлений нет..", 10)
		ShellExecute($DestFile) ;Run($DestFile)
EndIf


Func _Ftp_Get_File($S_File, $D_File, $user='anonymous', $pass='anonymous',$delete=False)
;прогресс бар
    ;Если callback-функция уже запущена (см. комменты далее), нет смысла продолжать далее (Return = выход из функции).
    If $hCallBack <> 0 Then Return
	
    ;Включаем диалог прогресса
    ProgressOn($sProgress_Title, $sProgress_MainText, $sProgress_SubText, -1, -1, 16)
;прогресс бар
		; Выделяем имя файла
		Local $S_File_name = $S_File
		Local $S_SrvName = $S_File
		Local $strSwitch = True

		While $strSwitch
			if StringInStr ( $S_File_name, '/' ) then
				$S_File_name = StringTrimLeft ( $S_File_name, StringInStr ( $S_File_name, '/' ) )
			Else
				$strSwitch = False
			EndIf
		WEnd
		; Выделяем имя файла
			if StringLeft ($S_SrvName,6) = 'ftp://' Then
				$S_SrvName = StringTrimLeft ( $S_SrvName, 6  )
				$S_File = StringTrimLeft ( $S_File , 6  )
			EndIf
			$S_SrvName = StringTrimRight ( $S_SrvName, StringLen($S_SrvName) - StringInStr ( $S_SrvName, '/' ) +1 );выделяем имя сервера
			$S_File = StringTrimLeft($S_File , StringLen($S_SrvName))
			$S_File = StringTrimRight($S_File, StringLen($S_File_name));выделяем путь ФТП
			$Open = _FTP_Open('MyFTP Control')
			$Conn = _FTP_Connect($Open, $S_SrvName, $user, $pass)
			_FTP_DirSetCurrent($Conn, $S_File)
			_FTP_FileGet ($Conn, $S_File_name, $D_File)
			if $delete then _FTP_FileDelete($Conn, $S_File_name)
			_FTP_Close($Open)
	ProgressSet(50, "Завершено", "Полностью выполнено")
EndFunc

;;##########################################################
;прогресс бар
;Это и есть callback-функция
Func _Callback_ProgressSet_Proc($hWnd, $iIDEvent, $iElapse, $pTimerFunc)
    ;Прибавляем 2 к главному счётчику (для прогресса)
    $iProgress_InitSet += 2

    ;Если счётчик перевалил за 100, обнуляем его, чтобы прогрес работал с начала.
    If $iProgress_InitSet > 100 Then $iProgress_InitSet = 0

    ;Задаём текузий прогресс
    ProgressSet($iProgress_InitSet, StringFormat($sProgress_SubText, $iProgress_InitSet))
EndFunc
;/прогресс бар
 
Верх