Что нового

[Ошибки] Нестабильное взаимодействие с окном телнет; зависит от MsgBox...

akoulev

Новичок
Сообщения
169
Репутация
2
Есть вот такой код:
Код:
#include <Array.au3>
Opt("TrayIconDebug", 1); Отладко-режим - в трее смотрим: в какой сроке "зависло"?
Dim $Pidowo [2]
Global $PIDGEON = 0;
$PIDGEON = Run ( "telnet.exe")
;MsgBox(4096,"$PIDDY", "$PIDGEON = """  & $PIDGEON & """")
Sleep(2222)
$Pidowo = _ProcessGetWindow($PIDGEON)
MsgBox(4096,"$sPunto_Window", "$PIDGEON = """ & $Pidgeon & """"  & @CR & "$Pidowo [0] = """ &  $Pidowo[0] & """"  & @CR & "$Pidowo[1] = """ & $Pidowo[1] & """")
WinClose( $Pidowo[1] )

Opt("TrayIconDebug", 0); Отладко-режим - в трее смотрим: в какой сроке "зависло"?
Exit


Func _ProcessGetWindow($iPID, $iRet=-1)
    Local $aWinList = WinList()
    Local $aRet[2]
    
    If IsString($iPID) Then $iPID = ProcessExists($iPID)
    
    For $i = 1 To UBound($aWinList)-1
        If WinGetProcess($aWinList[$i][1]) = $iPID Then
            $aRet[0] = $aWinList[$i][0] ;Title
            $aRet[1] = $aWinList[$i][1] ;WinHandle
            
            If $iRet = 0 Then Return $aRet[0]
            If $iRet = 1 Then Return $aRet[1]
            
            Return $aRet
        EndIf
    Next
    
    Return SetError(1, 0, $aRet)
EndFunc


Если в 6-й строке убрать точку с запятой, то всё работает (запуск телнета, пара окон; закрытие теленета); если точку с запятой восстановить (отключить первое из окон) — скрипт полностью рассыпается: Func больше не определяет имени окна телнета; окно телнета, также, уже не закрывается. WTF? Ай нид хелп, плиз! :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вы должны использовать функцию WinWait(), чтобы дождаться появления окна.
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
Спасибо; но, увы: так тоже не работает. Func так и не определяет имени окна телнета; => окно телнета, также, не закрывается. Кстати,в изначальном варианте стоял Sleep(2222) — этого более чем достаточно для запуска телнета.

Код:
#include <Array.au3>
Opt("TrayIconDebug", 1); Отладко-режим - в трее смотрим: в какой сроке "зависло"?
Dim $Pidowo [2]
Global $PIDGEON = 0;
$PIDGEON = Run ( "telnet.exe")
;MsgBox(4096,"$PIDDY", "$PIDGEON = """  & $PIDGEON & """")
WinWait("C:\WINDOWS\system32\telnet.exe")
Sleep(2222)
$Pidowo = _ProcessGetWindow($PIDGEON)
MsgBox(4096,"$sPunto_Window", "$PIDGEON = """ & $Pidgeon & """"  & @CR & "$Pidowo [0] = """ &  $Pidowo[0] & """"  & @CR & "$Pidowo[1] = """ & $Pidowo[1] & """")
WinClose( $Pidowo[1] )

Opt("TrayIconDebug", 0); Отладко-режим - в трее смотрим: в какой сроке "зависло"?
Exit


Func _ProcessGetWindow($iPID, $iRet=-1)
    Local $aWinList = WinList()
    Local $aRet[2]
    
    If IsString($iPID) Then $iPID = ProcessExists($iPID)
    
    For $i = 1 To UBound($aWinList)-1
        If WinGetProcess($aWinList[$i][1]) = $iPID Then
            $aRet[0] = $aWinList[$i][0] ;Title
            $aRet[1] = $aWinList[$i][1] ;WinHandle
            
            If $iRet = 0 Then Return $aRet[0]
            If $iRet = 1 Then Return $aRet[1]
            
            Return $aRet
        EndIf
    Next
    
    Return SetError(1, 0, $aRet)
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
akoulev
А так:
Код:
$sFile_Title = @SystemDir & '\telnet.exe'
$sProcess = 'telnet.exe'
Run($sFile_Title)
$iPID = ProcessWait($sProcess, 5)
If Not $iPID Then
	MsgBox(16, 'Error', 'Не дождались процесса telnet.exe :(')
	Exit
EndIf
$hWin = WinWait('[Title:' & $sFile_Title & ';Class:ConsoleWindowClass]', '', 5)
If Not $hWin Then
	MsgBox(16, 'Error', 'Нет окна telnet.exe :(')
Else
	MsgBox(64, 'Info', 'Handle ' & $sFile_Title & ': ' & $hWin)
EndIf
If MsgBox(36, 'Question', 'Закрыть окно ' & $sFile_Title & '?') = 6 Then
	WinClose($hWin)
EndIf

ИМХО, Ваша функция _ProcessGetWindow() не будет правильно работать, если процесс создает более 1-го окна. Тот же telnet.exe создает при запуске 3 окна (2 из них скрытые - у меня на Windows XP) и функция выдает первое найденное по PID, а это может быть как раз скрытое.

При запущенном вручную telnet.exe запустите этот скрипт для проверки и найдите там 3 его окна с одинаковым PID:
Код:
#include <Array.au3>
#include <WinAPIEx.au3>

$aList = WinList()
ReDim $aList[$aList[0][0] + 1][4]
For $i = 1 To $aList[0][0]
	$iPID = WinGetProcess($aList[$i][1])
	$aList[$i][2] = $iPID
	$sPath = _WinAPI_GetProcessFileName($iPID)
	$aList[$i][3] = $sPath
Next
_ArrayDisplay($aList)
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
Огромное спасибо! Да, так всё работает; правда, телнет у меня даёт только 2 окна, а не три, — но и этого хватало для полнометражного глюка. Ещё раз, спасибо!!!
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
Немножко уточню: на самом-то деле, мне надо было не только запускать телнет, но ещё и передавать в него IP-адрес: чтобы это сделать, пришлось ещё чуток поотлаживать...
Код не столь филигранно идеален, как у уважаемого madmasles,— но вполне рабочий:

Код:
$sIP_addr = "192.168.192.168"
$sFile_Title = @SystemDir & '\' & 'Telnet'  & ' ' & $sIP_addr ; НАЙДЕН грустнЫЙ IP
$sProcess = 'telnet.exe'
Run($sFile_Title)

$iPID = ProcessWait($sProcess, 2)

If Not $iPID Then
    MsgBox(16, 'Error', 'Не дождались процесса telnet.exe :(')
    Exit
EndIf

;$hWin = WinWait('[Title:' & "Telnet 192.168.192.168" & ';Class:ConsoleWindowClass]', '', 2) ; работает — но удручает явность (а не переменность!) IP-адреса.
$hWin = WinWait('[Title:' & "Telnet " & $sIP_addr & ';Class:ConsoleWindowClass]', '', 2)


If Not $hWin Then
    MsgBox(16, 'Error', 'Нет окна telnet.exe :(')
Else
EndIf
    WinClose($hWin)
 
Верх