jackylee0908 Posted December 25, 2024 Posted December 25, 2024 Hi, I have generated a batch file i.e. apc_off.bat to control a outlet from a APC PDU, below is the code: @echo off && setlocal enabledelayedexpansion echo/ && cls && color 9F && %__APPDIR__%mode.com 77,30 && set "_temp_vbs=%tmp%\_tmp_file_vbs_.vbs" && >"!_temp_vbs!"^ ( echo= On Error Resume Next echo= Set WshShell = WScript.CreateObject("WScript.Shell"^) echo= Set ObjShell = WScript.CreateObject("WScript.Shell"^) echo= Wsh.sleep 1000 'adjust this timeout for your needs echo= ObjShell.AppActivate "MS Telnet CMD" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "o 192.168.1.104~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "olOff 1~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "exit~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "^]" echo= Wsh.sleep 1000 echo= WshShell.SendKeys "quit~" ) && pushd %windir%\system32\ & title <nul && title MS Telnet CMD start "" /b "%__APPDIR__%cScript.exe" //nologo "!_temp_vbs!" && call telnet.exe :loop tasklist.exe /nh | findstr.exe /i cscript.exe >nul && goto :loop 2>nul >nul del /q /f "!_temp_vbs!" & popd & endlocal & exit It will pop a MS CMD window and execute a telnet command to turn on or off the outlet from the APC PDU, and when it is finished, the script will auto terminate the window. I try to add the apc_off.bat into AutoIT script like below: #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GUIListBox.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <Date.au3> #include <Process.au3> #include <Array.au3> #include <File.au3> #include <ScreenCapture.au3> #include <WinAPIFiles.au3> RunWait(@ComSpec & " /c" & "start " & "/wait" & " " & "apc_off.bat", @WorkingDir, @SW_HIDE) And try to run it, but I got the error message: It is strange because I try to open a cmd window and run the telnet.exe from the same folder of the AutoIT script it is workable, no idea why telnet could not recognized if I run it in AutoIT thru the batch file. Please help. Thanks, Jacky
argumentum Posted December 25, 2024 Posted December 25, 2024 ..run it in 64bit. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted December 25, 2024 Posted December 25, 2024 (edited) ..or #include "_RunWaitEx.au3" ; https://www.autoitscript.com/forum/topic/139260-autoit-snippets/?do=findComment&comment=1478119 #include <WinAPIFiles.au3> _WinAPI_Wow64EnableWow64FsRedirection ( False ) ConsoleWrite( _RunWaitEx("telnet /?") & @CRLF) Edit: may need to #RequireAdmin Edited December 25, 2024 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted December 25, 2024 Posted December 25, 2024 (edited) ..what a pain. I'd TCP to the telnet server. Unfortunately I don't have any telnet servers to play with and test. Edited December 25, 2024 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
jackylee0908 Posted December 25, 2024 Author Posted December 25, 2024 @argumentum Thanks but it doesn't work for me.
Nine Posted December 25, 2024 Posted December 25, 2024 (edited) Here what is working for me (seems there is quite a number of limitations starting Telnet from AutoIt) : #AutoIt3Wrapper_UseX64=y #include <Constants.au3> Opt("WinTitleMatchMode", -2) Run("telnet.exe") WinWait("Telnet") Send("?" & @CR) Send("^a") Sleep(200) Send("^c") MsgBox($MB_OK, "", ClipGet()) ps. just noticed that you lack a space after /c (but why concatenate multiple strings ?) RunWait(@ComSpec & " /c start /wait apc_off.bat", @WorkingDir, @SW_HIDE) Edited December 25, 2024 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
jackylee0908 Posted December 26, 2024 Author Posted December 26, 2024 18 hours ago, Nine said: Here what is working for me (seems there is quite a number of limitations starting Telnet from AutoIt) : #AutoIt3Wrapper_UseX64=y #include <Constants.au3> Opt("WinTitleMatchMode", -2) Run("telnet.exe") WinWait("Telnet") Send("?" & @CR) Send("^a") Sleep(200) Send("^c") MsgBox($MB_OK, "", ClipGet()) ps. just noticed that you lack a space after /c (but why concatenate multiple strings ?) RunWait(@ComSpec & " /c start /wait apc_off.bat", @WorkingDir, @SW_HIDE) Thanks, but seems it could not auto send keys into telnet cmd window. I have another solution but it might be stupid. I made a executable apc_control.exe by below AutoIT code: #include <Constants.au3> RunWait(@ComSpec & " /c" & " " & "start " & "/wait" & " " & "apc_onoff.bat" & " " & $CmdLine[1], @WorkingDir, @SW_HIDE) And, create another batch apc_onoff.bat file with below content: expandcollapse popup@echo off && setlocal enabledelayedexpansion if {%1}=={on} goto poweron if {%1}=={off} goto poweroff :poweron echo/ && cls && color 9F && %__APPDIR__%mode.com 77,30 && set "_temp_vbs=%tmp%\_tmp_file_vbs_.vbs" && >"!_temp_vbs!"^ ( echo= On Error Resume Next echo= Set WshShell = WScript.CreateObject("WScript.Shell"^) echo= Set ObjShell = WScript.CreateObject("WScript.Shell"^) echo= Wsh.sleep 2000 'adjust this timeout for your needs echo= ObjShell.AppActivate "MS Telnet CMD" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "o 192.168.1.104~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "olOn 7~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "olOn 8~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "exit~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "quit~" echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "quit~" ) && pushd %windir%\system32\ & title <nul && title MS Telnet CMD start "" /b "%__APPDIR__%cScript.exe" //nologo "!_temp_vbs!" && call telnet.exe goto loop :poweroff echo/ && cls && color 9F && %__APPDIR__%mode.com 77,30 && set "_temp_vbs=%tmp%\_tmp_file_vbs_.vbs" && >"!_temp_vbs!"^ ( echo= On Error Resume Next echo= Set WshShell = WScript.CreateObject("WScript.Shell"^) echo= Set ObjShell = WScript.CreateObject("WScript.Shell"^) echo= Wsh.sleep 2000 'adjust this timeout for your needs echo= ObjShell.AppActivate "MS Telnet CMD" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "o 192.168.1.104~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "apc~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "olOff 7~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "olOff 8~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "exit~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "quit~" echo= WshShell.SendKeys "~" echo= Wsh.sleep 2000 echo= WshShell.SendKeys "quit~" ) && pushd %windir%\system32\ & title <nul && title MS Telnet CMD start "" /b "%__APPDIR__%cScript.exe" //nologo "!_temp_vbs!" && call telnet.exe :loop tasklist.exe /nh | findstr.exe /i cscript.exe >nul && goto :loop 2>nul >nul del /q /f "!_temp_vbs!" & popd & endlocal & exit And in main AutoIT script, call the apc_control.exe to turn on/off the PDU outlet port: RunWait(@ComSpec & " /c" & "apc_control.exe off", @WorkingDir, @SW_HIDE) I understand it is stupid but since the main AutoIT script is with x86 but not x64 so I need to create a x64 apc_control.exe and call by the main script. But there is a risk that when telnet cmd window is pop out, if any interruption by human i.e. swith to other window then it will make the auto send key on another window but not the telnet cmd window, how could I make the cmd window hide or even on top screen so that to avoid any interruption? Thanks.
jackylee0908 Posted December 27, 2024 Author Posted December 27, 2024 I got another way from below link: Tried to update the example code to below one and confirmed it works well, but I don't know how to jump out the 'While' loop. #Include <INet.Au3> TcpStartUp () $remoteserver = tcpconnect("192.168.1.104", "23") ;client 2 TELNETserver, leave "TCPNameToIP" out if you have IP only. 23 is telnetport. if $remoteserver = -1 Then Exit While 1 sleep ('100'); $Recv1 = TCPRecv($remoteserver, "1000");1000 means max stringlen. $Username = "apc" $password = "apc" consolewrite($recv1);what the server replies If stringinstr($recv1, "User Name :") > 0 Then tcpsend($remoteserver, $Username & @crlf) Elseif stringinstr($recv1, "Password :") > 0 then tcpsend($remoteserver, $password & @crlf) Elseif stringinstr($recv1, "apc>") > 0 then tcpsend($remoteserver, "olOn 7" & @crlf) sleep ('100') tcpsend($remoteserver, "olOn 8" & @crlf) sleep ('100') tcpsend($remoteserver, "quit" & @crlf) Elseif stringinstr($recv1, "Connection to host lost") > 0 then msgbox(16,"error","Connection lost to host") EndIf Wend
Solution argumentum Posted December 27, 2024 Solution Posted December 27, 2024 (edited) 1 hour ago, jackylee0908 said: don't know how to jump out the 'While' loop. tcpsend($remoteserver, "quit" & @crlf) ExitLoop also, $Recv1 = TCPRecv($remoteserver, "1000");1000 means max stringlen. If @error Then ExitLoop ..that should do it. and: $Username = "apc" $password = "apc" can be moved outside the loop. might as well put it together ( for clarity ) expandcollapse popup#include <INet.Au3> doTheThing() Func doTheThing() TCPStartup() Local $remoteserver = TCPConnect("192.168.1.104", 23) ;client 2 TELNETserver, leave "TCPNameToIP" out if you have IP only. 23 is telnetport. If $remoteserver = -1 Then TCPShutdown() Return EndIf Local $Recv1, $iSleep = 200, $Username = "apc", $password = "apc" While 1 Sleep($iSleep) ; $Recv1 = TCPRecv($remoteserver, 1024) If @error Then ExitLoop ; TCPRecv() is not receiving ConsoleWrite($Recv1) ;what the server replies If StringInStr($Recv1, "User Name :") > 0 Then TCPSend($remoteserver, $Username & @CRLF) ElseIf StringInStr($Recv1, "Password :") > 0 Then TCPSend($remoteserver, $password & @CRLF) ElseIf StringInStr($Recv1, "apc>") > 0 Then TCPSend($remoteserver, "olOn 7" & @CRLF) Sleep($iSleep) TCPSend($remoteserver, "olOn 8" & @CRLF) Sleep($iSleep) TCPSend($remoteserver, "quit" & @CRLF) ExitLoop ; you're done ElseIf StringInStr($Recv1, "Connection to host lost") > 0 Then MsgBox(16, "error", "Connection lost to host") ExitLoop EndIf WEnd TCPCloseSocket($remoteserver) $remoteserver = -1 TCPShutdown() EndFunc ;==>doTheThing Edited December 27, 2024 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
jackylee0908 Posted December 30, 2024 Author Posted December 30, 2024 On 12/27/2024 at 10:13 AM, argumentum said: tcpsend($remoteserver, "quit" & @crlf) ExitLoop also, $Recv1 = TCPRecv($remoteserver, "1000");1000 means max stringlen. If @error Then ExitLoop ..that should do it. and: $Username = "apc" $password = "apc" can be moved outside the loop. might as well put it together ( for clarity ) expandcollapse popup#include <INet.Au3> doTheThing() Func doTheThing() TCPStartup() Local $remoteserver = TCPConnect("192.168.1.104", 23) ;client 2 TELNETserver, leave "TCPNameToIP" out if you have IP only. 23 is telnetport. If $remoteserver = -1 Then TCPShutdown() Return EndIf Local $Recv1, $iSleep = 200, $Username = "apc", $password = "apc" While 1 Sleep($iSleep) ; $Recv1 = TCPRecv($remoteserver, 1024) If @error Then ExitLoop ; TCPRecv() is not receiving ConsoleWrite($Recv1) ;what the server replies If StringInStr($Recv1, "User Name :") > 0 Then TCPSend($remoteserver, $Username & @CRLF) ElseIf StringInStr($Recv1, "Password :") > 0 Then TCPSend($remoteserver, $password & @CRLF) ElseIf StringInStr($Recv1, "apc>") > 0 Then TCPSend($remoteserver, "olOn 7" & @CRLF) Sleep($iSleep) TCPSend($remoteserver, "olOn 8" & @CRLF) Sleep($iSleep) TCPSend($remoteserver, "quit" & @CRLF) ExitLoop ; you're done ElseIf StringInStr($Recv1, "Connection to host lost") > 0 Then MsgBox(16, "error", "Connection lost to host") ExitLoop EndIf WEnd TCPCloseSocket($remoteserver) $remoteserver = -1 TCPShutdown() EndFunc ;==>doTheThing @argumentum Thanks, it did work for me. But I met another issue, I just created another post here:
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now