Что нового

[Ошибки] Ошибка в скрипте приводит к "Error allocating memory"

  • Автор темы at
  • Дата начала
A

at

Гость
Здравствуйте.
Выложил скрипт, который наблюдает за удаленной рабочей станцией. В течении дня один-два раза появляется сообщение об ошибке "Error allocating memory". Пожалуйста, подскажите, в чем причина.
Код:
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.6.1
 Author: Anton Czekhov 2011

 Script Function:
	Monitoring and automation trading.

#ce ----------------------------------------------------------------------------

While 1 ;основной цикл

    Sleep(100) ;пауза, чтобы процессор не грузился
    $vSpam = WinGetHandle('', 'Недопустимое окно') ;получаем хэндл текущего окна 'Недопустимое окно'
     If $vSpam Then ;если есть окно 'Недопустимое окно'(его хэндл), тогда
	   While WinExists('', 'Недопустимое окно') ;цикл (пока сушествуют окна 'Недопустимое окно')>>
		 Sleep(100) ;пауза, чтобы процессор не грузился
		 WinClose('', 'Недопустимое окно') ;>> закрываем все окна 'Недопустимое окно'
	   WEnd ;конец цикла (все окна 'Недопустимое окно' закрыты)
     EndIf

    Sleep(100) ;пауза, чтобы процессор не грузился
    $vExit = WinGetHandle('Сбой приема') ;получаем хэндл текущего окна 'Сбой приема'
     If $vExit Then ;если есть окно 'Сбой приема'(его хэндл), тогда
         Sleep(10000) ;делаем паузу 10 секунд, за это времямя все должны появиться все возможные окна 'Сбой приема'
         Close() ;вызываем функцию Close
     EndIf
	
    Sleep(100) ;пауза, чтобы процессор не грузился
	$vFileSmsIn = FileOpen('C:\Program Files\Control\simpl\autoread.txt', 0) ;открываем файл для чтения autoread.txt
    $vLineSmsIn = FileReadLine($vFileSmsIn) ;получаем текст
     Switch StringRight($vLineSmsIn, 1) ;сравниваем текст по условию
	 Case 'S' ;если в конце текста латинская 'S', тогда
		 Start() ;вызываем функцию Start, запускаем приложение в режиме F2
     Case 'R' ;если в конце текста латинская 'R', тогда
		 Rezerv() ;вызываем функцию Rezerv
	 Case 'M' ;если в конце текста латинская 'M', тогда
		 Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора	 
	 EndSwitch
	
WEnd

Func Close() ;функция Close
    While WinExists('Сбой приема') ;цикл (пока сушествуют окна 'Сбой приема')>>
        Sleep(100) ;пауза, чтобы процессор не грузился
        WinClose('Сбой приема') ;>> закрываем все окна 'Сбой приема'
    WEnd ;конец цикла (все окна 'Сбой приема' закрыты)
    SMS() ;вызываем функцию SMS
	
	 Sleep(10000) ;делаем паузу 10 секунд
      WinClose('G ') ;закрываем окно
     Sleep(10) ;пауза, чтобы процессор не грузился
      WinClose('S ') ;закрываем окно
     Sleep(10) ;пауза, чтобы процессор не грузился
      WinClose('l ') ;закрываем окно
     Sleep(10) ;пауза, чтобы процессор не грузился
      WinClose('G') ;закрываем окно
     Sleep(10) ;пауза, чтобы процессор не грузился
      WinClose('S') ;закрываем окно
     Sleep(10) ;пауза, чтобы процессор не грузился
      WinClose('l') ;закрываем окно
EndFunc

Func SMS() ;функция SMS
$vTextpozG = ControlGetText('G', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна
$vTextpozS = ControlGetText('S', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна
$vTextpozL = ControlGetText('l', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна

$vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 2) ;Перезаписываем файл SimpleSMSlite.txt
     FileWrite($vFileSmsOut,'79163667335;M;L;') ;Вносим в файл SimpleSMSlite.txt номер сотового телефона получателя
	  FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt

$vTextG5 = WinGetHandle('G') ;получаем хэндл текущего окна 'G'
$vTextS5 = WinGetHandle('S') ;получаем хэндл текущего окна 'S'
$vTextL5 = WinGetHandle('L') ;получаем хэндл текущего окна 'L'

$vTextG1 = WinGetHandle('G') ;получаем хэндл текущего окна 'G'
$vTextS1 = WinGetHandle('S') ;получаем хэндл текущего окна 'S'
$vTextL1 = WinGetHandle('L') ;получаем хэндл текущего окна 'L'

$vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 1);Дописываем файл SimpleSMSlite.txt
If $vTextG5 Then
	 FileWrite($vFileSmsOut,'G5=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozG) ;Добавляем значения из окна
       FileWrite($vFileSmsOut,': ');Добавляем в текст разделитель
EndIf
If $vTextS5 Then
     FileWrite($vFileSmsOut,'S5=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozS) ;Добавляем значения из окна
       FileWrite($vFileSmsOut,': ');Добавляем в текст разделитель
EndIf
If $vTextL5 Then
     FileWrite($vFileSmsOut,'L5=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozL) ;Добавляем значения из окна
       FileWrite($vFileSmsOut,': ');Добавляем в текст разделитель
EndIf

If $vTextG1 Then
	 FileWrite($vFileSmsOut,'G6=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozG) ;Добавляем значения из окна
       FileWrite($vFileSmsOut,': ');Добавляем в текст разделитель
EndIf
If $vTextS1 Then
	 FileWrite($vFileSmsOut,'S6=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozS) ;Добавляем значения из окна
	   FileWrite($vFileSmsOut,': ');Добавляем в текст разделитель
EndIf
If $vTextL1 Then
     FileWrite($vFileSmsOut,'L6=');Добавляем сообщение
	  FileWrite($vFileSmsOut,$vTextpozL) ;Добавляем значения из окна
EndIf
	
     FileWrite($vFileSmsOut,'.');Добавляем точку
      FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt
	 ShellExecute('simplesmslite.exe', 'ERR=3', 'C:\Program Files\Control\simpl\') ;запускаем программу Simplesms (отправляем sms)
EndFunc

Func Start() ;функция Start, запускаем приложение
	    FileOpen('C:\Program Files\Control\simpl\autoread.txt', 2) ;удаляем содержимое файла autoread.txt
		 Sleep(100) ; пауза
          FileChangeDir('C:\Program Files\Control\') ; указываем каталог программы
           Run('Robot.exe') ;запускаем файл Robot.exe
		FileClose($vFileSmsIn)
		Sleep(10000) ;делаем паузу 10 секунд
		SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc
	
Func Rezerv() ;резервная функция
	    FileOpen('C:\Program Files\Control\simpl\autoread.txt', 2) ;удаляем содержимое файла autoread.txt
         MsgBox(0, 'Info', 'Резервная функция')
		FileClose($vFileSmsIn)
EndFunc
	  
Func Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора
	    FileOpen('C:\Program Files\Control\simpl\autoread.txt', 2) ;удаляем содержимое файла autoread.txt
		 Sleep(100) ; пауза
          FileChangeDir('C:\Program Files\Control\') ; указываем каталог программы
           Run('Robot_monitor.exe') ;запускаем файл Robot_monitor.exe
		FileClose($vFileSmsIn)
		Sleep(10000) ;делаем паузу 10 секунд
		SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
218
Файлы, открытые с помощью FileOpen, должны быть закрыты с помощью FileClose.
Может из-за них.
 

AZJIO

Меценат
Меценат
Сообщения
2 755
Репутация
1 150
at

Сделал оптимизацию скрипта.

Код:
#cs ----------------------------------------------------------------------------

	AutoIt Version: 3.3.6.1
	Author: Anton Czekhov 2011

	Script Function:
	Monitoring and automation trading.

#ce ----------------------------------------------------------------------------
Global $vPath = 'C:\Program Files\Control\simpl\autoread.txt'

While 1 ;основной цикл

	Sleep(100) ;пауза, чтобы процессор не грузился
	$vSpam = WinGetHandle('', 'Недопустимое окно') ;получаем хэндл текущего окна 'Недопустимое окно'
	If $vSpam Then ;если есть окно 'Недопустимое окно'(его хэндл), тогда
		While WinExists('', 'Недопустимое окно') ;цикл (пока сушествуют окна 'Недопустимое окно')>>
			Sleep(100) ;пауза, чтобы процессор не грузился
			WinClose('', 'Недопустимое окно') ;>> закрываем все окна 'Недопустимое окно'
		WEnd ;конец цикла (все окна 'Недопустимое окно' закрыты)
	EndIf

	Sleep(100) ;пауза, чтобы процессор не грузился
	$vExit = WinGetHandle('Сбой приема') ;получаем хэндл текущего окна 'Сбой приема'
	If $vExit Then ;если есть окно 'Сбой приема'(его хэндл), тогда
		Sleep(10000) ;делаем паузу 10 секунд, за это времямя все должны появиться все возможные окна 'Сбой приема'
		Close() ;вызываем функцию Close
	EndIf

	Sleep(100) ;пауза, чтобы процессор не грузился
	$vLineSmsIn = FileRead($vPath) ;читаем файл для чтения autoread.txt
	Switch StringRight($vLineSmsIn, 1) ;сравниваем текст по условию
		Case 'S' ;если в конце текста латинская 'S', тогда
			Start() ;вызываем функцию Start, запускаем приложение в режиме F2
		Case 'R' ;если в конце текста латинская 'R', тогда
			Rezerv() ;вызываем функцию Rezerv
		Case 'M' ;если в конце текста латинская 'M', тогда
			Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора
	EndSwitch

WEnd

Func Close() ;функция Close
	While WinExists('Сбой приема') ;цикл (пока сушествуют окна 'Сбой приема')>>
		Sleep(100) ;пауза, чтобы процессор не грузился
		WinClose('Сбой приема') ;>> закрываем все окна 'Сбой приема'
	WEnd ;конец цикла (все окна 'Сбой приема' закрыты)
	SMS() ;вызываем функцию SMS

	Sleep(10000) ;делаем паузу 10 секунд
	WinClose('G ') ;закрываем окно
	Sleep(10) ;пауза, чтобы процессор не грузился
	WinClose('S ') ;закрываем окно
	Sleep(10) ;пауза, чтобы процессор не грузился
	WinClose('l ') ;закрываем окно
	Sleep(10) ;пауза, чтобы процессор не грузился
	WinClose('G') ;закрываем окно
	Sleep(10) ;пауза, чтобы процессор не грузился
	WinClose('S') ;закрываем окно
	Sleep(10) ;пауза, чтобы процессор не грузился
	WinClose('l') ;закрываем окно
EndFunc   ;==>Close

Func SMS() ;функция SMS
	$vTextpozG = ControlGetText('G', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна
	$vTextpozS = ControlGetText('S', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна
	$vTextpozL = ControlGetText('l', '', '[CLASS:TEdit; INSTANCE:20]') ;получаем значения из окна

	$vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 2) ;Перезаписываем файл SimpleSMSlite.txt
	FileWrite($vFileSmsOut, '79163667335;M;L;') ;Вносим в файл SimpleSMSlite.txt номер сотового телефона получателя
	FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt

	$vTextG5 = WinGetHandle('G') ;получаем хэндл текущего окна 'G'
	$vTextS5 = WinGetHandle('S') ;получаем хэндл текущего окна 'S'
	$vTextL5 = WinGetHandle('L') ;получаем хэндл текущего окна 'L'

	$vTextG1 = WinGetHandle('G') ;получаем хэндл текущего окна 'G'
	$vTextS1 = WinGetHandle('S') ;получаем хэндл текущего окна 'S'
	$vTextL1 = WinGetHandle('L') ;получаем хэндл текущего окна 'L'

	$vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 1);Дописываем файл SimpleSMSlite.txt
	
	$vText=''
	If $vTextG5 Then $vText&='G5='&$vTextpozG&': ' ;Добавляем сообщение, значения из окна, разделитель
	If $vTextS5 Then $vText&='S5='&$vTextpozS&': ' ;Добавляем сообщение, значения из окна, разделитель
	If $vTextL5 Then $vText&='L5='&$vTextpozL&': ' ;Добавляем сообщение, значения из окна, разделитель

	If $vTextG1 Then $vText&='G6='&$vTextpozG&': ' ;Добавляем сообщение, значения из окна, разделитель
	If $vTextS1 Then $vText&='S6='&$vTextpozS&': ' ;Добавляем сообщение, значения из окна, разделитель
	If $vTextL1 Then $vText&='L6='&$vTextpozL ;Добавляем сообщение, значения из окна

	FileWrite($vFileSmsOut, $vText&'.');Добавляем точку
	FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt
	ShellExecute('simplesmslite.exe', 'ERR=3', 'C:\Program Files\Control\simpl\') ;запускаем программу Simplesms (отправляем sms)
EndFunc   ;==>SMS

Func Start() ;функция Start, запускаем приложение
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	Sleep(100) ; пауза
	Run('C:\Program Files\Control\Robot_monitor.exe') ;запускаем файл Robot_monitor.exe
	Sleep(10000) ;делаем паузу 10 секунд
	SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc   ;==>Start

Func Rezerv() ;резервная функция
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	MsgBox(0, 'Info', 'Резервная функция')
EndFunc   ;==>Rezerv

Func Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	Sleep(100) ; пауза
	Run('C:\Program Files\Control\Robot_monitor.exe') ;запускаем файл Robot_monitor.exe
	Sleep(10000) ;делаем паузу 10 секунд
	SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc   ;==>Monitor
 
Автор
A

at

Гость
Спасибо за помощь. После оптимизации сравнил и увидел, что мой старый скрипт по нарастающей потихоньку забивает память. Ваш скрипт работает, как часики. Пожалуйста, объясните, где моя ошибка.
 

AZJIO

Меценат
Меценат
Сообщения
2 755
Репутация
1 150
at
Как было сказано выше - "незакрытые файлы". А вообще я не проверял работу, я просто закрыл файлы при вызове в функциях и в цикле.
Далее чтоб не делать многократную запись по кусочкам, сделал присоединение текста к переменной $vText и запись 1 раз.
 
Автор
A

at

Гость
Спасибо Всем. Мне все понятно.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 320
at,
Попробовал еще немного оптимизировать:
Код:
#cs ----------------------------------------------------------------------------
	
	AutoIt Version: 3.3.6.1
	Author: Anton Czekhov 2011
	
	Script Function:
	Monitoring and automation trading.
	
#ce ----------------------------------------------------------------------------
Global $vPath = 'C:\Program Files\Control\simpl\autoread.txt', _
		$aTitle[4][3] = [[3, 2],['G', '5', '6'],['S', '5', '6'],['L', '5', '6']], $fFunc

While 1 ;основной цикл
	If WinExists('', 'Недопустимое окно') Then
		Close('', 'Недопустимое окно') ;>> закрываем все окна 'Недопустимое окно'
	EndIf
	If WinExists('Сбой приема') Then ;если есть окно 'Сбой приема'(его хэндл), тогда
		Sleep(10000) ;делаем паузу 10 секунд, за это времямя все должны появиться все возможные окна 'Сбой приема'
		Close('Сбой приема', '', 1) ;вызываем функцию Close
		Sleep(10000) ;делаем паузу 10 секунд
		For $j = 1 To $aTitle[0][1]
			For $i = 1 To $aTitle[0][0]
				Close($aTitle[$i][0] & $aTitle[$i][$j])
			Next
		Next
		$fFunc = True
	EndIf
	If $fFunc Then
		$vLineSmsIn = FileRead($vPath) ;читаем файл для чтения autoread.txt
		Switch StringRight($vLineSmsIn, 1) ;сравниваем текст по условию
			Case 'S' ;если в конце текста латинская 'S', тогда
				Start() ;вызываем функцию Start, запускаем приложение в режиме F2
			Case 'R' ;если в конце текста латинская 'R', тогда
				Rezerv() ;вызываем функцию Rezerv
			Case 'M' ;если в конце текста латинская 'M', тогда
				Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора
		EndSwitch
		$fFunc = False
	EndIf
	Sleep(100) ;пауза, чтобы процессор не грузился
WEnd

Func Close($s_Title, $sText = '', $i_Flag = 0) ;функция Close
	While WinExists($s_Title, $sText)
		WinClose($s_Title, $sText)
		Sleep(100) ;пауза, чтобы процессор не грузился
	WEnd
	If $i_Flag Then
		SMS() ;вызываем функцию SMS
	EndIf
EndFunc   ;==>Close

Func SMS() ;функция SMS
	Local $vText, $sTEdit = '[CLASS:TEdit; INSTANCE:20]'
	Local $vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 2) ;Перезаписываем файл SimpleSMSlite.txt
	FileWrite($vFileSmsOut, '79163667335;M;L;') ;Вносим в файл SimpleSMSlite.txt номер сотового телефона получателя
	FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt
	For $j = 1 To $aTitle[0][1]
		For $i = 1 To $aTitle[0][0]
			If WinExists($aTitle[$i][0] & $aTitle[$i][$j]) Then $vText &= $aTitle[$i][0] & $aTitle[$i][$j] & '=' & ControlGetText($aTitle[$i][0] & $aTitle[$i][$j], '', $sTEdit) & ': ' ;Добавляем сообщение, значения из окна, разделитель
		Next
	Next
	$vFileSmsOut = FileOpen('C:\Program Files\Control\simpl\SimpleSMSlite.txt', 1);Дописываем файл SimpleSMSlite.txt
	FileWrite($vFileSmsOut, $vText & '.');Добавляем точку
	FileClose($vFileSmsOut) ;Закрываем файл SimpleSMSlite.txt
	ShellExecute('simplesmslite.exe', 'ERR=3', 'C:\Program Files\Control\simpl\') ;запускаем программу Simplesms (отправляем sms)
EndFunc   ;==>SMS

Func Start() ;функция Start, запускаем приложение
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	Sleep(100) ; пауза
	Run('C:\Program Files\Control\Robot_monitor.exe') ;запускаем файл Robot_monitor.exe
	Sleep(10000) ;делаем паузу 10 секунд
	SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc   ;==>Start

Func Rezerv() ;резервная функция
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	MsgBox(0, 'Info', 'Резервная функция')
EndFunc   ;==>Rezerv

Func Monitor() ;вызываем функцию Monitor, запускаем приложение в режиме монитора
	Local $File = FileOpen($vPath, 2) ;удаляем содержимое файла autoread.txt
	FileClose($File)
	Sleep(100) ; пауза
	Run('C:\Program Files\Control\Robot_monitor.exe') ;запускаем файл Robot_monitor.exe
	Sleep(10000) ;делаем паузу 10 секунд
	SMS() ;вызываем функцию SMS, отправляем информацию о состоянии приложения
EndFunc   ;==>Monitor
 
Автор
A

at

Гость
'Сбой приема' - Не закрылись два окна "L". Честно говоря, сам не смог найти ошибку.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 320
at [?]
'Сбой приема' - Не закрылись два окна "L".
Как, в какой последовательности и сколько раз появляются эти окна с буквой?
 
Автор
A

at

Гость
Как, в какой последовательности и сколько раз появляются эти окна с буквой?
Окна открыты постоянно. Пока их шесть (предполагается добавление в будущем). Закрываются в такой последовательности: G5, S5, L5, G6, S6, L6. Скрипт принудительно закрывает их после возникновения информационного окна с ошибкой 'Сбой приема'.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 320
at [?]
И так и так все окна остаются открытыми.
Какие у них точные заголовки и класс? В какой последовательности они появляются?
 

AZJIO

Меценат
Меценат
Сообщения
2 755
Репутация
1 150
madmasles
Я тоже хотел сделать массив, но не стал усложнять вид. Был бы смысл если бы эту операцию сделать в памяти, но как я понял из скрипта: файл autoread.txt изменяется внешним приложением, так как в цикле запрашиваются буквы S, R, M, а сам скрипт их туда не добавляет.
Единственное я бы увеличил задержку в "основной цикл", время одного шага 0,3 сек, т.е. 3 раза в секунду читается файл. Неужели требуется так часто?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 320
AZJIO [?]
но как я понял из скрипта: файл autoread.txt изменяется внешним приложением
at ничего не говорил об этом, а я, к моему глубокому сожалению, не телепат, и на чтение файла я поставил условие и он читается-проверяется только при появлении окна 'Сбой приема'. Может быть это и неправильно, я не знаю.
 
Автор
A

at

Гость
Скрипт наблюдает за приложениями Delphi которые смотрят в интернет. Всего их шесть, они так и называются (G5, S5, L5, G6, S6, L6).
Для этого я задал в скрипте три цикла: два первых для наблюдения и один для управления скриптом через программу simplesmslite.
1.Цикл следит за появлением окна с ошибкой «Недопустимое окно»;
2.Цикл следит за появлением окна «Сбой приема», которое появляется при разрыве связи Интернет и закрывает шесть открытых приложений, за которыми наблюдает (G5, S5, L5, G6, S6, L6);
3.Цикл следит за информацией в файле autoread.txt, которую в него добавляет внешняя программа simplesmslite.exe. Буквы (S, R, M) - это внешние команды скрипту через СМС-сообщение.

В данном случае ошибка связана со вторым циклом. Я пытался разобраться сам, но запутался, много переменных. Первоначально скрипт от madmasles не закрывал только окна приложений L5 и L6. Приложения закрывались у меня в следующем порядке: G5=>S5=>L5=>G6=>S6=>L6, хотя это не имеет принципиального значения.
 
Верх