Что нового

[Автоматизация] Автоматическое обновление файлов

sashazzz

Новичок
Сообщения
10
Репутация
1
Суть проблемы:есть ряд exe-шников которые необходимо обновлять с сервера по мере их обновления на самом сервере.Например,на рабочем столе у пользователя есть ярлык,назовем его "Sklad",сам exe-шник лежит тут C:\Rabota\Sklad.exe . Нужно сделать следующее:пользователь кликает по ярлыку,скрипт лезет на сервер,к примеру, \\192.168.0.50\Rabota и сверяет exe-шник кторой лежит в C:\Rabota\Sklad.exe с тем что лежит на сервере.Если дата екзешника на сервере более ранняя,то нужно заменить екзешник в папке C:\Rabota\Sklad.exe екзешником с сервера. Сравнивать нужно по дате,по тому что размер бывает один и тот же!
Таких екзешников много,около 100 штук и писать под каждый екзешник отдельный скрипт не целесоборазно.

Желательно что бы при этом сточка в ярлыке выглядела так "C:\Rabota\autoupd.exe \\192.168.0.50\Rabota\sklad.exe"

Версия AutoIt: 3.3.6.1

Описание:

Примечания:
 

axlwor

Скриптер
Сообщения
657
Репутация
147
версии файлов и хэши отменили. :whistle:
А если запустить вторую, третью и далее копию как пойдет обновление?
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
Мне без разницы как будет происходить сравнение файлов,главное это конечный результат!!!
 

axlwor

Скриптер
Сообщения
657
Репутация
147
Код:
copy \\server\share\sklad.exe %cd%\
sklad.exe
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
у меня не один exe-шник,а штук 100.Нужно сднлать что бы они обновлялись одним скриптом,а не для каждого писать скрипт отдельно!
 

axlwor

Скриптер
Сообщения
657
Репутация
147
Тогда я не понял задачи

Вариант 1. Ты делаешь новую версию. Выкладываешь на шару. Запускаешь скрипт на сервере (или где то еще), и всем клиентам доходит новая версия. Соответственно клиенты не должны работать в этот момент, потому что экзешник "захвачен"

Вариант 2. Ты делаешь новую версию. Клиент перед началом работы запускает не экзешник, а мой скрипт. Обновляется до последней версии и запускает прогу

Вариант 3. При старте компа клиента запускается скрипт и обновляет ВСЕ ВСЕ ВСЕ.
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
Не один из трех вариантов не подходит.Объясню почему! 1)Не буду обзванивать 150 человек что бы они пока не работали,соответственно что бы небыли запущены екзешники!
2)Сначала надо тогда сделать 100 скриптов (потоу что 100 екзешников) так что ли?
Либо сделать 1 скрипт который обновляет все екзешники - это тоже самое что вариант 3.
3)Если сделать скрипт который будет обновлять все екзешники с сервера,то у некоторых пользователей это займет час,а то и более!И обновление может произойти в любой момент рабочего дня,соответственно нужно будет скрипт еще раз запускать!И какая будет нагрузка на сервер если 150 ПК будут одновременно обновлятся при включении :shok:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
sashazzz,
Не могу проверить с сервером, проверял только с папками. Если файл запущен, то закроет его, скопирует и опять запустит.
Код:
#NoTrayIcon

Opt('MustDeclareVars', 1)

Global $sPathNewExe = 'D:\NewExe', _ ;путь к папке с новыми exe-файлами
		$sPathSearchExe = @ProgramFilesDir & '\MyDir', _ ;путь к головной папке с exe-файлами для проверки (будет искать в самой папке и во всех подпапках)
		$iDateCreatedOld, $iDateCreatedNew, $iCountOK, $iCountError, $iPid, $sFileName, _
		$a_ExeFiles, $iPid

$a_ExeFiles = _FileSearch($sPathSearchExe, '*.exe', 1)
If @error Then Exit
For $i = 1 To $a_ExeFiles[0]
	$sFileName = StringRegExpReplace($a_ExeFiles[$i], '^.*\\', '')
	If @extended <> 1 Then ContinueLoop
	$iPid = ProcessExists($sFileName)
	$iDateCreatedOld = FileGetTime($a_ExeFiles[$i], 1, 1)
	If @error Then ContinueLoop
	If FileExists($sPathNewExe & '\' & $sFileName) Then
		$iDateCreatedNew = FileGetTime($sPathNewExe & '\' & $sFileName, 1, 1)
		If @error Then ContinueLoop
		If $iDateCreatedNew > $iDateCreatedOld Then
			If $iPid Then
				ProcessClose($iPid)
				If Not ProcessWaitClose($iPid, 5) Then
					$iCountError += 1
					ContinueLoop
				EndIf
			EndIf
			If FileCopy($sPathNewExe & '\' & $sFileName, $a_ExeFiles[$i], 1) Then
				If FileSetTime($a_ExeFiles[$i], $iDateCreatedNew, 1) Then
					$iCountOK += 1
				Else
					$iCountError += 1
				EndIf
				If $iPid Then Run($a_ExeFiles[$i])
			Else
				$iCountError += 1
			EndIf
		EndIf
	EndIf
Next
If $iCountOK Then
	MsgBox(64, 'Info', 'Успешно заменили файлов:' & $iCountOK)
EndIf
If $iCountError Then
	MsgBox(16, 'Error', 'Ошибок: ' & $iCountError)
EndIf

Func _FileSearch($s_Path_Search, $s_File_Mask = '*', $i_Flag = 0, $i_SubDir = 1)
	;фильтры для поиска нужно указывать через ;
	;$i_Flag = 0 - Файлы и папки (по умолчанию)
	;$i_Flag = 1 - Только файлы
	;$i_Flag = 2 - Только папки (если ищем конкретную папку, то надо добавлять к имени * в начало  или в конец)
	;$i_SubDir = 1 - Искать во всех подкаталогах (по умолчанию). Возвращает полные пути.
	;$i_SubDir = 0 - Искать только в самой папке. Возвращает только имена файлов(папок).
	Local $s_Out, $a_Out, $s_Read, $h_Dir, $s_Attrib, $s_Subdir, $a_Masks

	If StringRight($s_Path_Search, 1) == '\' Then ;нужно, если $s_Path_Search - диск (например C:\)
		$s_Path_Search = StringTrimRight($s_Path_Search, 1)
	EndIf
	If $i_SubDir Then
		$s_Subdir = ' /S /B'
	Else
		$s_Subdir = ' /B'
	EndIf
	Switch $i_Flag
		Case 1
			$s_Attrib = ' /A-D'
		Case 2
			$s_Attrib = ' /AD'
		Case Else
			$s_Attrib = ' /A'
	EndSwitch
	$s_Out = StringToBinary('0' & @CRLF, 2)
	$a_Masks = StringSplit($s_File_Mask, ';')
	For $i = 1 To $a_Masks[0]
		$h_Dir = Run(@ComSpec & ' /U /C DIR "' & $s_Path_Search & '\' & $a_Masks[$i] & '"' & $s_Subdir & $s_Attrib, @SystemDir, @SW_HIDE, 6)
		If Not $h_Dir Then Return SetError(1)
		While 1
			$s_Read = StdoutRead($h_Dir, False, True)
			If @error Then
				ExitLoop
			EndIf
			If $s_Read Then
				$s_Out &= $s_Read
			EndIf
			Sleep(10)
		WEnd
	Next
	$a_Out = StringRegExp(BinaryToString($s_Out, 2), '[^\r\n]+', 3)
	If @error Then Return SetError(1)
	$a_Out[0] = UBound($a_Out) - 1
	Return $a_Out
EndFunc   ;==>_FileSearch
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
проверил,скрипт работает,но желательно не все екзешники копировать,а только тот который запускают!Я же говорил,что копирование всех екзешников на некоторых ПК может занять длительное время!
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
Понимаете,в папке на сервере 100 екзешников (может и больше,не считал).Стоит сервер с ПО,у клиентов стоит клиентское ПО. Програма (не буду ее озвучивать как она называется) так скажем единая база данных,что для бухгалтерии,что для кладовщика,для любой другой службы. Так вот,у бухгалтера например,стоит свой ярлык назовем его "Бухгалтерия",у кладовщика свой,назовем его "склад".....так вот зачем например кладовщику обновлять екзешник Бухгалтерия,или например остальные какие то екзешники???!!!Ему это не нужно,поэтому нужно только что бы скрипт обновлял только тот экзешник,который нужно. Нужно что бы скрипт был ОДИН и работал следующим образом: создаем ярлык например
C:\Rabota\script.exe \\server\rabota\sklad.exe или например C:\Rabota\script.exe \\server\rabota\buhgalteria.exe и в зависимости какой ярлык запускается,Бухгалтерия или Склад,то и обновляется!!!Короче нужно что бы скрит был универсальный,т.е. он запускается с параметром,а параметром является екзешник,и что бы он его обновлял!!!!

Объясню еще ситуацию: раньше был некий файл autoupd.exe и ярлык выглядел след.образом C:\RABOTA\AUTOUPD.EXE \\SERVER\RABOTA\SKLAD.EXE так вот,он как раз и обновлял екзешник. Но потом этот файл вдруг перестал работать!!!Поэтому мне нужен скрипт что бы он работал по аналогии.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
sashazzz [?]
у клиентов стоит клиентское ПО
То есть, у кладовщика есть рабочий файл, который надо обновлять, Компьютер кладовщика\Диск\папка\кладовщик.exe, у бухгалтера - Компьютер бухгалтера\Диск\папка\бухгалтер.exe, и т.д.? А новые файлы кладовщик.exe, бухгалтер.exe, и т.д. (если они есть) лежат в папке \server\rabota\?
Я правильно понимаю? Если да, то файл exe, который надо обновлять, (Компьютер кладовщика\Диск\папка\кладовщик.exe и т.д.) один в папке (Компьютер кладовщика\Диск\папка\ и т.д.) или нет?
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
То есть, у кладовщика есть рабочий файл, который надо обновлять, Компьютер кладовщика\Диск\папка\кладовщик.exe, у бухгалтера - Компьютер бухгалтера\Диск\папка\бухгалтер.exe, и т.д.?
Да,все верно поняли!!!

А новые файлы кладовщик.exe, бухгалтер.exe, и т.д. (если они есть) лежат в папке \server\rabota\?
Все верно!!!

Если да, то файл exe, который надо обновлять, (Компьютер кладовщика\Диск\папка\кладовщик.exe и т.д.) один в папке (Компьютер кладовщика\Диск\папка\ и т.д.) или нет?
Он не один,но обновлять нужно только то,что в данный момент запускаем!!!Например можно создать на компе бухгалтера ярлык для запуска кладовщик.exe или наоборот,на компе кладовщика создать ярлык для запуска бухалтерии.
Нужно просто сделать 1 универсальный скрипт,для обновления любого exe-шника,понимаете!!!
Очень надо что бы работало все вот таким образом: C:\Rabota\скрипт обновления.exe \\server\rabota\бухгалтер.exe т.е. скрипт должен понять что он должен обновить файл бухгалтер.exe если вместо бухгалтер.exe поставить например кладовщик.exe, то скрипт должен сам уже понять что нужно обновить кладовщик.exe



Т.Е. поступают новые exe-шники например с датой 10.10.2011 бухгалтерия.exe и кладовщик от разработчика,затем они отправляются в папку \\server\rabota\ если там уже есть такие (а они там есть) же exe-шники то они заменяются,все это делается руками!!!

Пользователи не знают о существовании новых exe-шников!!!как только бухгалтер кликает по ярлыку на своем раб.столе, скрипт лезет на сервер,сверяет по дате и времени (или по еще какому то критерию) exe-шник который находится в локальной папке C:\RABOTA\ и на сервере \\server\rabota и если на сервере exe-шник свежее,то скрипт копирует с сервера новый exe-шник с заменой,а затем запускает его!!!
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
sashazzz,
Файлы, которые надо обновлять, на всех компьютерах находятся в папке Системный диск\rabota\?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
sashazzz,
Попробуйте так:
1. Updater. Его нужно скомпилировать в Updater.exe. Запускаться он должен только с параметрами (ярлыком, батником и т.д.). Если в момент запуска файл, который должен обновиться, запущен, то скрипт закроет его, обновит и запустит.
Код:
#NoTrayIcon

Opt('MustDeclareVars', 1)

If WinExists('{[/@[email protected]\]}Updater') Then Exit
AutoItWinSetTitle('{[/@[email protected]\]}Updater')

If Not @Compiled Then Exit
If Not $CmdLine[0] Then Exit
For $i = 1 To $CmdLine[0]
	_Get_New_Exe($CmdLine[$i])
	If @error Then
		TrayTip('Обновление файлов', 'Произошла ошибка обновления файла <' & $CmdLine[$i] & '>', 5, 3)
		Sleep(5000)
	EndIf
Next

Func _Get_New_Exe($s_FileName)
	Local $i_DateCreatedOld, $i_DateCreatedNew, $i_Pid, _
			$s_PathNewExe = 'D:\server\rabota';путь к папке с новыми exe-файлами (поменяйте на свой)

	If Not FileExists(@ScriptDir & '\' & $s_FileName) Then Return
	$i_Pid = ProcessExists($s_FileName)
	$i_DateCreatedOld = FileGetTime(@ScriptDir & '\' & $s_FileName, 1, 1)
	If @error Then Return SetError(1)
	If Not FileExists($s_PathNewExe & '\' & $s_FileName) Then Return
	$i_DateCreatedNew = FileGetTime($s_PathNewExe & '\' & $s_FileName, 1, 1)
	If @error Then Return SetError(1)
	If $i_DateCreatedNew > $i_DateCreatedOld Then
		If $i_Pid Then
			ProcessClose($i_Pid)
			If Not ProcessWaitClose($i_Pid, 5) Then Return SetError(1)
		EndIf
		If Not FileCopy($s_PathNewExe & '\' & $s_FileName, @ScriptDir & '\' & $s_FileName, 1) Then Return SetError(1)
		FileSetTime(@ScriptDir & '\' & $s_FileName, $i_DateCreatedNew, 1)
		If $i_Pid Then Run(@ScriptDir & '\' & $s_FileName)
	EndIf
EndFunc   ;==>_Get_New_Exe

2. Installer. Установит Updater.exe в выбранную папку и создаст ярлык в выбранной папке. В ярлыке, в качестве параметров запуска Updater.exe, будут указаны выбранные для обновления файлы. Updater.exe должен лежать в одной папке с installer при компиляции или при запуске из SciTE. После компиляции - без разницы.
Код:
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <File.au3>

Opt('MustDeclareVars', 1)
Opt('TrayMenuMode', 1)

Global $hGui, $nInputDirInstall, $nInputDirShortcut, $nButtonSelectInstall, $nButtonSelectShortcut, _
		$sPathShortcut, $nButtonInstall, $nInputDirShortcut, $nListView, $hListView, $sPathInstall, _
		$aFiles, $fSelect, $sParam, $iCount, $sFileName, $sTitle = 'Установка Updater'

If WinExists($sTitle & '{[/@[email protected]\]}') Then Exit
AutoItWinSetTitle($sTitle & '{[/@[email protected]\]}')

$hGui = GUICreate($sTitle, 305, 244, -1, -1, -1, $WS_EX_TOPMOST)
GUISetBkColor(0xF5F5DC)
$nInputDirInstall = GUICtrlCreateInput('Папка для установки Updater', 10, 10, 250, 22, _
		$ES_READONLY, $WS_EX_DLGMODALFRAME)
GUICtrlSetBkColor(-1, 0xDCDCDC)
$nButtonSelectInstall = GUICtrlCreateButton('...', 265, 9, 30, 24)
GUICtrlSetFont(-1, 16)
GUICtrlSetTip(-1, 'Выбрать папку для установки Updater')
GUICtrlSetCursor(-1, 0)
$nInputDirShortcut = GUICtrlCreateInput('Папка для создания ярлыка для Updater', 10, 42, 250, 22, _
		$ES_READONLY, $WS_EX_DLGMODALFRAME)
GUICtrlSetBkColor(-1, 0xDCDCDC)
$nButtonSelectShortcut = GUICtrlCreateButton('...', 265, 41, 30, 24)
GUICtrlSetFont(-1, 16)
GUICtrlSetTip(-1, 'Выбрать папку для создания ярлыка для Updater')
GUICtrlSetCursor(-1, 0)
$nButtonInstall = GUICtrlCreateButton('Установить', 100, 204, 105, 30)
GUICtrlSetTip(-1, 'Установить Updater для выбранных файлов')
GUICtrlSetCursor(-1, 0)
GUICtrlSetState(-1, $GUI_DISABLE)
$nListView = GUICtrlCreateListView('', 10, 74, 285, 120, $LVS_SINGLESEL, BitOR($LVS_EX_GRIDLINES, $LVS_EX_CHECKBOXES))
$hListView = GUICtrlGetHandle(-1)
_GUICtrlListView_AddColumn($hListView, 'Файлы для обновления', 275)

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nButtonSelectInstall
			$sPathInstall = FileSelectFolder('Выберите папку для установки Updater', '', 2, '', $hGui)
			If @error Or Not FileExists($sPathInstall) Then
				$sPathInstall = ''
				ContinueLoop
			EndIf
			If $fSelect Then
				_GUICtrlListView_DeleteAllItems($hListView)
			EndIf
			$aFiles = _FileListToArray($sPathInstall, '*.exe', 1)
			If @error Then
				GUICtrlSetData($nInputDirInstall, 'Ошибка поиска файлов *.exe')
				GUICtrlSetState($nButtonInstall, $GUI_DISABLE)
				GUICtrlSetTip($nListView, '')
				ContinueLoop
			Else
				GUICtrlSetData($nInputDirInstall, $sPathInstall)
			EndIf
			For $i = 1 To $aFiles[0]
				If $aFiles[$i] <> 'Updater.exe' Then
					_GUICtrlListView_AddItem($hListView, $aFiles[$i])
				EndIf
			Next
			$fSelect = True
			GUICtrlSetTip($nListView, 'Отметьте файлы, которые надо обновлять')
			If FileExists(GUICtrlRead($nInputDirShortcut)) Then
				GUICtrlSetState($nButtonInstall, $GUI_ENABLE)
			EndIf
			$sPathInstall = ''
			$aFiles = 0
		Case $nButtonSelectShortcut
			$sPathShortcut = FileSelectFolder('Выберите папку для установки ярлыка для Updater', '', 2, '', $hGui)
			If @error Or Not FileExists($sPathShortcut) Then
				$sPathShortcut = ''
				ContinueLoop
			EndIf
			GUICtrlSetData($nInputDirShortcut, $sPathShortcut)
			If FileExists(GUICtrlRead($nInputDirInstall)) Then
				GUICtrlSetState($nButtonInstall, $GUI_ENABLE)
			EndIf
			$sPathShortcut = ''
		Case $nButtonInstall
			$sPathInstall = GUICtrlRead($nInputDirInstall)
			If Not FileExists($sPathInstall) Then ContinueLoop
			$sPathShortcut = GUICtrlRead($nInputDirShortcut)
			If Not FileExists($sPathShortcut) Then ContinueLoop
			$iCount = _GUICtrlListView_GetItemCount($hListView)
			If Not $iCount Then ContinueLoop
			For $i = 0 To $iCount - 1
				If _GUICtrlListView_GetItemChecked($hListView, $i) Then
					$sFileName = _GUICtrlListView_GetItemText($hListView, $i)
					If StringInStr($sFileName, Chr(32)) Then $sFileName = '"' & $sFileName & '"'
					$sParam &= $sFileName & Chr(32)
				EndIf
			Next
			If Not $sParam Then ContinueLoop
			$sParam = StringTrimRight($sParam, 1)
			If MsgBox(33, $sTitle, 'Папка установки Updater:' & @CRLF & '<' & $sPathInstall & '>' & _
					@CRLF & @CRLF & 'Папка создания ярлыка для Updater:' & @CRLF & '<' & $sPathShortcut & '>' & _
					@CRLF & @CRLF & 'Будут обновляться файл(ы): ' & $sParam & _
					@CRLF & @CRLF & 'OK - установить и создать ярлык' & @CRLF & _
					'Отмена - отменить', 0, $hGui) <> 1 Then ContinueLoop
			If Not FileInstall('Updater.exe', $sPathInstall & '\Updater.exe', 1) Then
				TrayTip($sTitle, 'Произошла ошибка установки файла Updater', 5, 3)
			EndIf
			If FileExists($sPathShortcut & '\Обновление.lnk') Then FileDelete($sPathShortcut & '\Обновление.lnk')
			If Not FileCreateShortcut($sPathInstall & '\Updater.exe', $sPathShortcut & '\Обновление.lnk', '', _
					$sParam, 'Обновление файла(ов) ' & $sParam, $sPathInstall & '\Updater.exe') Then
				TrayTip($sTitle, 'Произошла ошибка создания ярлыка для Updater', 5, 3)
			EndIf
			GUICtrlSetState($nButtonInstall, $GUI_DISABLE)
			$iCount = 0
			$sParam = ''
	EndSwitch
WEnd

Проверял только на одном компьютере, возможности проверить по сети нет.

PS
Для Updater при компиляции выберите иконку, она будет установлена и для ярлыка.
 
Автор
S

sashazzz

Новичок
Сообщения
10
Репутация
1
Откомпилил,но не совсем пойу как его запусукать с параметром!!!пример приведите!
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
sashazzz [?]
Откомпилил,но не совсем пойму как его запусукать с параметром!
Запускаете Installer, в появившемся окне выбираете папку с файлами, которые надо будет обновлять. Ставите галку у тех файлов, которые будут обновляться. Выбираете папку для создания ярлыка. Жмете кнопку Установить. Installer установит Updater в выбранную папку и создаст для него ярлык в выбранной папке и именем Обновление и параметрами запуска Updater. Параметры вида кладовщик.exe или кладовщик.exe бухгалтер.exe и т.д. Все. Теперь, если запустить Updater ярлыком Обновление, то он проверит в папке, в которой лежит, заданные файлы на дату создания, проверит их наличие и дату создания в папке D:\server\rabota (поменяйте на свой путь) и, при необходимости, их заменит на новые.
Проверял только на одном компьютере, возможности проверить по сети нет, у меня работает.
 

DinamitMobile

Новичок
Сообщения
2
Репутация
0
Доброго времени суток! Являюсь админом, на добровольной основе, игрового сервера TeknoMW3 в LAN сети. В данная игре множество обновлений выходит. Постоянно приходится расшаривать эти обновления, что занимает определённое количество времени и постоянные недовольства игроков. Хотелось бы автоматизировать этот процесс. А возможно ли переделать Ваш скрипт под мои данные? Я полный чайник в написании скриптов с неуёмным желанием сделать людям хорошо.
На сервере игры сделаю папку Update в директории 172.22.100.101 G:\mw3 multiplayer\Update
В ней хочу разместить файлы и папки с файлами. Эта папка будет эталоном, с которого, при наличии обновления, файлы должны попасть к игроку на компьютер в директорию C:\Call of Duty, в которой имеются и файлы и папки с файлами. И обновление должно удалять устаревшие файлы.
Буду очень Вам благодарен за помощь в написании скрипта!
 
Верх