Что нового

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

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
Репутация
219
Файлы, открытые с помощью FileOpen, должны быть закрыты с помощью FileClose.
Может из-за них.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
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,874
Репутация
1,194
at
Как было сказано выше - "незакрытые файлы". А вообще я не проверял работу, я просто закрыл файлы при вызове в функциях и в цикле.
Далее чтоб не делать многократную запись по кусочкам, сделал присоединение текста к переменной $vText и запись 1 раз.
 

madmasles

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

at

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

madmasles

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

AZJIO

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
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, хотя это не имеет принципиального значения.
 
Верх