Jump to content

Trying to read the data in mainframe screen but not able to


viswat88
 Share

Recommended Posts

Hi Team,

I am new to this Autoit and trying to learn. I started to create auto login for a mainframe system. I can open the mainframe with Autoit script but once WIndow opened, I wanted to read mainframe screen and send commands according to the screen stage..

For example, below is the mainframe screen which is opened through autoit script, now once opened I wanted to read if the window is having "USERID"

I tried WinGetText, Controlgettext etc.. but all are giving blank results.. 

Below is summary from Window Info..and attached the screen which i want to read.. Any suggestions will really help me much.. I am still searching online, if anyone already posted similar queries or solutions.. Thanks and waiting for your inputs..

>>>> Window <<<<
Title:    Tulsa - [24 x 80]
Class:    PCSWS:Main:00400000
Position:    -8, -8
Size:    1616, 876
Style:    0x15CF0000
ExStyle:    0x00000100
Handle:    0x0000000000AD0FA6

>>>> Control <<<<
Class:    
Instance:    
ClassnameNN:    
Name:    
Advanced (Class):    
ID:    
Text:    
Position:    
Size:    
ControlClick Coords:    
Style:    
ExStyle:    
Handle:    

>>>> Mouse <<<<
Position:    745, 20
Cursor ID:    0
Color:    0xBFFBFF

>>>> StatusBar <<<<
1:    
2:    Connected to remote server/host 10.192.254.181 using port 23
3:    HP Universal Printing PCL 6 on LPT1:

>>>> ToolsBar <<<<

>>>> Visible Text <<<<


>>>> Hidden Text <<<<
Hardcopy Window

 

 

Screen from where I want to read data.JPG

Link to comment
Share on other sites

I am guessing that this is a Unix-like system terminal.  There are no Windows Controls on that screen.  I do not think Autoit will work for that.

Also, how does the user interaction work?  If all it wants is 3 entries consequential, have AutoIt ControlSend() each in turn.

Skysnake

Why is the snake in the sky?

Link to comment
Share on other sites

IIRC this is IBMs Personal Communications product. They come with an API so you can automate them.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

http://sourceforge.net/projects/x3270/

you probably can rebuild in AutoIT

In the past with RationalRobot I automated a system like this with some advanced screenscraping

Approach (in about 5000 lines of code a very powerfull automation system) sounds clumsy but in the end it worked fully in a very stable way

1.   Make sure you can read x and y position of the cursor in the statusbar

2.   Make sure you can go with home key or other key to a "known" position on the screen

3.   Automate the screen by numbering fields. So first you do home key and you are in field 1, with tab you are in field 2

4.  Make sure you have a select all / copy all to clipboard (which you can read in AutoIT in a string)

5.  Count fields on a screen by a. get start x and y from status bar.   b. sending tab key and count tabs until you are back at starting x and y

6. In Excel we then made just about 50 lines (for each field 1 line) and enduser could type a description column and a value column (internally it was just a field number ref)

Link to comment
Share on other sites

I agree with junkew, I'm also happly using that sw to access mainframe via 3270.
A note: there is no need to install that package, you can download the noinstall.zip version from the download session of the x3270 site (http://x3270.bgp.nu/index.html)it contains various versions of that sw, and I think that the most usefull to be used by AutoIt is the "ws3270.exe". This exe allows you to manage 3270 sessions via I/O streams (without a GUI). In this way you can automate all via script instead of try to interact with the gui. (at the beginning this way can seem more harder, but in the long term is the easier and powerfull way)
So, just copy the content of the "wc3270-3.4ga7-noinstall.zip"  file to a folder accessible from your script.
Then use a way similar to the following script to interact with the mainframe:
The following is a little "not working" example, just to show one of the possibles "modus operandi"  and a way to begin to do some try.
Have a look to the various doc pages on the "documentation" link of that site to see all the commands an options available.
p.s.
the ws3270 sw also allows you to make ssl connections. If that is requested from your host, you have to use few more free files and startup parameters in that case.

#include <Constants.au3>

; run the ws3270 with some optional config parameters and in I/O streams mode.
Global $ws3270 = Run('3270\wS3270.exe -model 3278-2 -port 23', @ScriptDir, @SW_SHOW, $STDIN_CHILD + $STDOUT_CHILD)

; following commands are just for an example
; ------------------------------------------
StdinWrite($ws3270, "connect(10.192.254.181)" & @LF) ;      connect to mainframe
$status = GetStatus() ;                                     wait the output from the host (a sort of ready to go ahead)
; -------------------
StdinWrite($ws3270, "enter()" & @LF) ;                      send an "enter" to mainframe
$status = GetStatus()
; -------------------
StdinWrite($ws3270, 'string("zVM\n")' & @LF) ;              sends the string zVM and 'enter' (of course this is a fantasy command
;                                                                                             use the commands that you should type
;                                                                                             on the keyboard, via io stream instead.
$status = GetStatus()
; -------------------
StdinWrite($ws3270, 'Clear' & @LF) ;                        send the "Clear" keystroke
$status = GetStatus()
; -------------------
StdinWrite($ws3270, 'string("loginx\n")' & @LF) ;           send command loginx to mainframe (fantasy command here, use true commands instead)
$status = GetStatus()
StdinWrite($ws3270, 'Ascii(22,7,10)' & @LF) ;               ask to ws2370 to return screen output from row,col,length
$status = GetStatus()
If StringInStr($status, "USERID") Then MsgBox(0, 0, "got userid request")
StdinWrite($ws3270, 'MoveCursor(18,21)' & @LF) ;            position cursor to coordinates row,column 0 BASED!
; -------------------
StdinWrite($ws3270, 'String("MyUserID\n")' & @LF) ;         send credentials
$status = GetStatus()
StdinWrite($ws3270, 'MoveCursor(19,21)' & @LF)
StdinWrite($ws3270, 'String("MyPassword\n")' & @LF)
$status = GetStatus()
StdinWrite($ws3270, 'string("' & $MyAutoitVariable & '\n")' & @LF) ; example to send the content of a variable
$status = GetStatus()
StdinWrite($ws3270, 'Ascii(10,1,12,79)' & @LF) ;                     request for a square area from the output
$status = GetStatus()
 ; clean and copy the returned square (rows,cols) to an array
Local $avLines = StringSplit(StringStripWS(StringStripCR(StringReplace($status, @LF, Chr(30))), 7), Chr(30))
; each row of the array contains each row of the returned square area
_ArrayDisplay($avLines)

StdinWrite($ws3270, 'PF(8)' & @LF) ; send PF8
$status = GetStatus()
StdinWrite($ws3270, 'PF(3)' & @LF) ; send PF3
$status = GetStatus()
; -------------------

StdinWrite($ws3270, "Ascii" & @LF) ; the ascii command with no parameters will request the entire screen to stdout
$status = GetStatus()
MsgBox(0, "", $status & @CRLF) ; show the returned "screenshot"

; StdinWrite($ws3270) ; close input stream
; ---
; END
; ---
;
; this will get the output from 3270 (from ws3270 stdout stream)
Func GetStatus($Print = 1, $timeout = 60)
    ; if $Print = 1 -> Print Status on console (for debug purpose)
    ; $timeout = max secs to wait output before setting error

    $timer = TimerInit()
    $out = ""
    Do
        $out = StdoutRead($ws3270, False, False) ; get output from 3270 stdout stream
        Sleep(100)

        If TimerDiff($timer) / 1000 > $timeout Then
            ; $out = "error: Timeout"
            ConsoleWrite("error: timeout " & Int(TimerDiff($timer) / 1000) & " sec." & @CRLF)
            Return SetError(1, 0, $out)
            ; Exit
        EndIf

    Until $out <> ""

    If $Print Then ConsoleWrite($out & @CRLF)
    Return $out

EndFunc   ;==>GetStatus

 

Edited by Chimp
correction to the x3270 site link

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

I have activex solusion but not on my smartphone,  So you must wait When i back home.

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

Thanks to all of you and suggestions!! I will try with x3270 what Chimp and Junkew suggested. 

mLipok, please share your thoughts too whenever you get time. Thanks again to all!!

I will update here how my experience goes with x3270 and get you back if i need some help. Thanks!!

Link to comment
Share on other sites

I have looked at http://www.ttwin.com/

for the tulsa program.

This is similar product to Aterm

 

This is ActiveX COM object for TN3270

http://www.jtsoft.com.pl/index.php?option=com_content&task=view&id=7&Itemid=14

This is Polish program with Polish English and Russian interface. But the doc is only in Polish.

As I see the price for Tulsa is comparable to Aterm.
I also sse that Tulsa also have ActiveX in feature list.

 

So are you still intrested ?

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

Hi Chimp.. 

I tried to download x3270 as suggested and simply ran below

 

#include <Constants.au3>

; run the ws3270 with some optional config parameters and in I/O streams mode.
 local $ws3270 = Run('C:\Users\Autoit\wc3270-3.4ga7-noinstall\wS3270.exe -model 3278-2 -port 23', @ScriptDir, @SW_SHOW, $STDIN_CHILD + $STDOUT_CHILD)

 StdinWrite($ws3270, "connect(10.192.254.181)" & @LF) ;      connect to mainframe

with this script, I am seeing a window opened up (looks like command prompt window) but i dont see it connecting to mainframe.. 

I just want to see how it connects mainframe and hit commands on mainframe based on content in mainframe screen.. 

Please suggest if am doing something wrong.. Thanks a lot for your time and support..

 

Link to comment
Share on other sites

you should look at getStatus function in anser of Chimp. You have to read the response yourself into a variable with that function.

You probably will not see anything on the screen unless you put it there with a write or specific action yourself.

The most reliable way to send commands to wc3270 and ws3270 on Windows is with the -scriptport option.

http://x3270.bgp.nu/Unix/x3270-script.html

some python example reference for learning

http://pydoc.net/Python/py3270/0.2.0/py3270/

 

 

Link to comment
Share on other sites

Hi viswat88

when you redirect the i/o streams of an application (ws3270.exe in our case), you have:

  1. the big advantage that you can completely manage that application from your script, "subjugating" it to your needs
  2. the little disadvantage that you completely lose the view of what's happening on the application's own screen.

Because of point 2, you have to check what's going on, not with your eyes, but using script functions to peeking data and comparing with string functions for example.
anyway, I agree that can be of help to see the output "screenshots" of the program for an easier and quicker feedback,
though perhaps it is better to do the analysis of what you want to automate on the original program and then program the needed commands using the I/O streams and hide the black and useless screen of the program when is in I/O stream mode.
Here is a minimalist listing that should help you to test the vs3270.exe against your 3270 host server. I've also included a "simulated" 3270 screen to check "visually" if the connection to 3270 was successful. If so you should see the 3270 welcome response to your connection request on the simulated screen.

(Important note: when I issue a "connect" request, usually I get response after about 20-30 secs. Wait a little bit before you lose hope)
Let us know what happens.

#include <Constants.au3>
#include <EditConstants.au3>

; -- this window will simulates a regular 3270 screen with rows and columns numbers on top and left edges as a quick reference ---
Global $hCRT = GUICreate("3270 Output preview", 850, 505)
GUICtrlCreateLabel("0         1         2         3         4         5         6         7" & @CRLF & _
        "01234567890123456789012345678901234567890123456789012345678901234567890123456789", 33, 5, 820)
GUICtrlSetFont(-1, 12, 400, 0, "courier new")
GUICtrlCreateLabel(" 0" & @CRLF & " 1" & @CRLF & " 2" & @CRLF & " 3" & @CRLF & " 4" & @CRLF & " 5" & @CRLF & " 6" & @CRLF & _
        " 7" & @CRLF & " 8" & @CRLF & " 9" & @CRLF & "10" & @CRLF & "11" & @CRLF & "12" & @CRLF & "13" & @CRLF & "14" & @CRLF & _
        "15" & @CRLF & "16" & @CRLF & "17" & @CRLF & "18" & @CRLF & "19" & @CRLF & "20" & @CRLF & "21" & @CRLF & "22" & @CRLF & _
        "23" & @CRLF & "24", 3, 44, 50, 500)
GUICtrlSetFont(-1, 12, 400, 0, "courier new")
Global $hEdit = GUICtrlCreateEdit("", 30, 40, 820, 465, $ES_READONLY)
GUICtrlSetFont(-1, 12, 400, 0, "courier new")
GUICtrlSetBkColor(-1, 0)
GUICtrlSetColor(-1, 0x00FF00)
GUISetState(@SW_SHOW)
; --------------------------------------------------------------------------------------------------------------------------------

; run the ws3270 with some optional config parameters in I/O streams mode and hidden.
Global $ws3270 = Run('3270\wS3270.exe -model 3278-2 -port 23', @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
; -model 3278-2 --> 80 COLUMNS - 24 ROWS (columns-> 0-79  rows-> 0-23)
;
StdinWrite($ws3270, "connect(10.192.254.181)" & @LF) ; try to connect to mainframe
;
$status = GetStatus() ;                                wait the response from the host and get response in $status
ScreenShot3270() ;                                     "copy" the output of the 3270 real screen to the simulated 3270 screen

MsgBox(0, 0, "Pause") ;                                pause before end

StdinWrite($ws3270, "Disconnect" & @LF) ;  use a safe logout from 3270 host (change this as required from your 3270 host)
StdinWrite($ws3270) ;                      close stream
GUIDelete($hCRT) ;                         delete window
; -------
; THE END
; -------
;
; this will get the output from 3270 (from ws3270 stdout stream)
Func GetStatus($Print = 0, $timeout = 60)
    ; if $Print = 1 -> Print Status on console (for debug purpose)
    ; $timeout = max secs to wait response from host before setting error

    Local $timer = TimerInit()
    Local $sOut = ""
    Do
        $sOut = StdoutRead($ws3270, False, False) ; get output from 3270 stdout stream
        Sleep(100)

        If TimerDiff($timer) / 1000 > $timeout Then
            $sOut = "error: timeout " & Int(TimerDiff($timer) / 1000) & " sec."
            Return SetError(1, 0, $sOut)
            ; Exit
        EndIf
    Until $sOut <> "" ; stay here till a response (or timeout)

    If $Print Then ConsoleWrite($sOut & @CRLF)
    Return SetError(0, 0, $sOut)
EndFunc   ;==>GetStatus

Func ScreenShot3270() ; print output to the 3270 simulated screen
    ; see how to use the Ascii function here: http://x3270.bgp.nu/Windows/wc3270-script.html
    ; Ascii without parameters will take the entire screen
    StdinWrite($ws3270, "Ascii()" & @LF) ; take a snapshod of the entire 3270 screen
    Local $sSnapShot = GetStatus() ; wait and get answer from host
    ; since the ascii function adds data: to the beginning of each line, i will remove it
    $sSnapShot = StringReplace($sSnapShot, "data: ", "")
    GUICtrlSetData($hEdit, $sSnapShot) ; put the snapshot to the simulated 3270 screen
EndFunc   ;==>ScreenShot3270

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 1 month later...

Sorry to bump, just adding some code to look at that I wrote based off of what I learned from this thread. Hopefully it'll help anyone trying to automate 3270. I have some particular functions that make it easy to progress through screens. I usually have a session open and go through steps 1-by-1 to pull what data I need to "check for". The methods I used also prevent the script from inputting data before it's ready to.

I believe I've removed all important data from the code below.

 

The purpose of this code is for Helpdesk Analysts to unlock an ID on a mainframe server. It saves about 45 seconds each time they use it, prevents them from needing to know the 3270 syntax (or having reference the kb we have), and assist them in saving/updating their own password when needed.

#include <GuiConstants.au3>
#include <Crypt.au3>
#include <Array.au3>

FileWriteLine(@ScriptDir & "\logs\!LAUNCH.dst", @MDAY & "~!~" & @ComputerName & "~!~" & @UserName)

Local $con = IniReadSection(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection")
If @error = 1 Then
   DirCreate(@AppDataDir & "\DST-Reset-Tool\")
   IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "ID", StringEncrypt(True, "MM#####"))
   IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "PW", StringEncrypt(True, "temp"))
   $con = IniReadSection(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection")
EndIf
If Not FileExists(@AppDataDir & "\DST-Reset-Tool\ws3270.exe") Then FileCopy(@ScriptDir & "\bin\ws3270.exe", @AppDataDir & "\DST-Reset-Tool\ws3270.exe")

Local $GUI = GuiCreate("DST Reset", 200, 100)
Local $IDi = GUICtrlCreateInput("", 5, 5, 80, 20)
Local $idic = GUICtrlCreateDummy()
Local $LOOK = GUICtrlCreateButton("Lookup/Enable", 90, 5, 105, 20)
Local $CRED = GUICtrlCreateLabel("Your Credentials", 60, 35, 90, 13)
Local $usL = GUICtrlCreateLabel("ID:", 12, 55, 19, 13)
Local $pwL = GUICtrlCreateLabel("PW:", 5, 80, 50, 13)
Local $usI = GUICtrlCreateInput("", 30, 51, 80, 20)
Local $pwI = GUICtrlCreateInput("", 30, 76, 80, 20, BitOR($ES_PASSWORD, $ES_AUTOHSCROLL))
Local $TEST = GUICtrlCreateButton("Test", 120, 55, 70, 40)
GUISetState()

GUICtrlSetData($usI, StringEncrypt(False, $con[1][1]))
GUICtrlSetData($pwI, StringEncrypt(False, $con[2][1]))

Local $curID = ""
Local $ws3270, $status
Local $step
Local $expired

Local $gMsg
While 1
   $gMsg = GUIGetMsg()
   Switch $gMsg
   Case $LOOK
      If GuiCtrlRead($idi) = "" Then
         MsgBox(48, "Input Error", "You did not enter an ID", 0, $GUI)
      Else
         If StringLen(GuiCtrlRead($idi)) > 8 Then
            MsgBox(48, "Input Error", "You entered an ID longer than the max ID length. (8)", 0, $GUI)
         Else
            $curID = GuiCtrlRead($idi)
            $step = 10
            DST()
         EndIf
      EndIf
   Case $TEST
      $step = 8
      DST(True)
   Case $idic
      Local $idif = GuiCtrlRead($idi)
      If StringRegExp($idif, "[^0-9A-Z]") Then GUICtrlSetData($IDi, StringUpper(StringRegExpReplace($idif,"[^0-9a-zA-Z]","")))
   Case $GUI_EVENT_CLOSE
      Exit
   EndSwitch
WEnd

Func DST($test = False)
   IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "ID", StringEncrypt(True, GUICtrlRead($usI)))
   IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "PW", StringEncrypt(True, GUICtrlRead($pwI)))
   $expired = False
   ToolTip("Running DST Step 1/" & $step)
   $ws3270 = Run('"' & @AppDataDir & '\DST-Reset-Tool\ws3270.exe" -model 3279-2', @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
   ToolTip("Running DST Step 2/" & $step)
   Send3270("connect(*SERVER REMOVED*)")
   WaitFor(2, 0, 8, "TERMINAL")
   ToolTip("Running DST Step 3/" & $step)
   Send3270("String(menu)", 1)
   WaitFor(0, 22, 11, "DST Systems")
   ToolTip("Running DST Step 4/" & $step)
   Send3270("String(pma)", 1)
   WaitFor(0, 1, 17, "ENTER TRANSACTION")
   ToolTip("Running DST Step 5/" & $step)
   Send3270("String(pma)", 1)
   WaitFor(3, 1, 13, "ENTER REQUEST")
   ToolTip("Running DST Step 6/" & $step)
   Send3270("String(eoper)", 2)
   ToolTip("Running DST Step 7/" & $step)
   Send3270("String(" & GUICtrlRead($usI) & ")", 2)
   ToolTip("Running DST Step 8/" & $step)
   Send3270("String(" & GUICtrlRead($pwI) & ")", 1)
   Local $res = MultiWait(1)
   If $test Then $uid = "LOGIN-TEST"
   FileWriteLine(@ScriptDir & "\logs\DST-RESET_SCRIPT-LOGS-" & @YEAR & @MON & @MDAY & ".awd", @HOUR & ":" & @MIN & "~!~PERFORMED" & "~!~" & $curID & "~!~" & @UserName)
   If $test Then $uid = ""
   ToolTip("")
   Switch $res
   Case 0
      Local $goodpw = True
      If $expired Then
         $goodpw = False
         Local $badpw = "Your password has expired"
         Local $pwerror = ""
         While 1
            Local $xpw = InputBox("Password Expired", $badpw & ", please input a new password; 7-8 characters, including 1 number." & $pwerror)
            If @error = 1 Then ExitLoop
            $pwerror = ""
            Send3270("String(" & $xpw & ")", 1)
            Send3270("Ascii(1,1,60)")
            If StringMid($status, 7, 7) = "LOGN.28" Then
               Send3270("String(" & $xpw & ")", 1)
               GUICtrlSetData($pwI, $xpw)
               $goodpw = True
               MsgBox(64, "Successful", "Your password has been changed and saved.", 0, $GUI)
               ExitLoop
            Else
               $badpw = "The system did not accept your input and returned the following message"
               $pwerror = @CRLF & "Error: " & StringStripWS(StringMid($status, 7, 60), 3)
            EndIf
         WEnd
      EndIf
      If $goodpw Then
         IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "ID", StringEncrypt(True, GUICtrlRead($usI)))
         IniWrite(@AppDataDir & "\DST-Reset-Tool\settings.ini", "Connection", "PW", StringEncrypt(True, GUICtrlRead($pwI)))
         If $test Then
            MsgBox(64, "Successful", "Authentication successful, your credentials have been saved.")
         Else
            ToolTip("Running DST Step 9/" & $step)
            Send3270("String(" & $curID & ")")
            If StringLen($curID) < 8 Then Send3270("tab()")
            Send3270("enter()")
            $res = MultiWait(2)
            Switch $res
            Case 0
               ToolTip("Running DST Step 10/" & $step)
               Send3270("Ascii(14,31,30)")
               Local $uname = StringStripWS(StringMid($status, 7, 30), 3)
               ToolTip("")
               If MsgBox(36, "Select Action", "ID found and is disabled." & @CRLF & "Full Name: " & $uname & @CRLF & "YES - To enable" & @CRLF & "NO - To do nothing") = 6 Then
                  Send3270("enter()")
                  WaitFor(23, 41, 7, "ALREADY")
                  MsgBox(48, "Successfully Enabled", "Successfully Enabled, the password is the first 7 characters of their last name." & @CRLF & "Full Name: " & $uname)
               EndIf
            Case 1
               MsgBox(48, "Error", "The ID you input is already enabled.")
            Case 2
               MsgBox(48, "Error", "The ID you input does not exist.")
            Case 4
               MsgBox(48, "Error", "The request timed out, please try again.")
            EndSwitch
         EndIf
      EndIf
   Case 1
      MsgBox(48, "Error", "Invalid Credentials, please update and try again.")
   Case 2
      MsgBox(48, "Error", "You do not have access to the 'eoper' function in DST.")
   Case 3
      MsgBox(48, "Error", "Your ID is logged into another instance of DST, please disconnect that session and try again.")
   Case 4
      MsgBox(48, "Error", "The request timed out for some reason, please verify your credentials and try again.")
   Case 5
      MsgBox(48, "Error", "Your ID is disabled, please have an associate re-enable it for you.")
   Case 6
      MsgBox(48, "Error", "Invalid Credentials; also, your ID is logged into another instance of DST, please disconnect that session and try again..")
   Case 7
      MsgBox(48, "Error", "Your ID does not exist, please ensure you entered it correctly.")
   EndSwitch
   Send3270("Disconnect()")
   ProcessClose("ws3270.exe")
EndFunc

Func Send3270($data, $add = 0)
   StdinWrite($ws3270, $data & @LF)
   $status = GetStatus(1, 60, $data)
   If $add = 1 Then
      StdinWrite($ws3270, "enter()" & @LF)
      $status = GetStatus(1, 60, "enter()")
   ElseIf $add = 2 Then
      StdinWrite($ws3270, "tab()" & @LF)
      $status = GetStatus(1, 60, "tab()")
   EndIf
EndFunc

Func GetStatus($Print = 1, $timeout = 60, $msg = "")
    ; if $Print = 1 -> Print Status on console (for debug purpose)
    ; $timeout = max secs to wait output before setting error
    $timer = TimerInit()
    $out = ""
    Do
        $out = StdoutRead($ws3270, False, False) ; get output from 3270 stdout stream
        Sleep(100)
        If TimerDiff($timer) / 1000 > $timeout Then
            ; $out = "error: Timeout"
            ConsoleWrite("error: timeout " & Int(TimerDiff($timer) / 1000) & " sec." & @CRLF)
            Return SetError(1, 0, $out)
            ; Exit
        EndIf
    Until $out <> ""
    If $Print Then ConsoleWrite($msg & @CRLF & $out & @CRLF)
    Return $out
EndFunc

Func WaitFor($row, $col, $len, $data = "")
   Local $time = TimerInit()
   While Round(TimerDiff($time)) < 60000
      Send3270("Ascii(" & $row & "," & $col & "," & $len & ")")
      If StringMid($status, 7, $len) = $data Then ExitLoop
      Sleep(500)
   WEnd
EndFunc

Func MultiWait($tog)
   Local $time = TimerInit()
   While Round(TimerDiff($time)) < 60000
      If $tog = 1 Then
         Send3270("Ascii(1,33,6)")
         If StringMid($status, 7, 6) = "ENABLE" Then Return 0
         Send3270("Ascii(1,1,7)")
         If StringMid($status, 7, 7) = "LOGN.10" Then Return 1 ;Invalid Creds
         If StringMid($status, 7, 7) = "LOGN.04" Then Return 5 ;ID Disabled
         If StringMid($status, 7, 7) = "LOGN.17" Then Return 5 ;ID Disabled
         If StringMid($status, 7, 7) = "LOGN.12" Then Return 6 ;Invalid creds and another connected session
         If StringMid($status, 7, 7) = "LOGN.02" Then Return 7 ;ID Doesn't Exist
         If StringMid($status, 7, 7) = "LOGN.11" Then ;Password Expired
            $expired = True
            Return 0
         EndIf
         Send3270("Ascii(5,7,7)")
         If StringMid($status, 7, 7) = "REQUEST" Then Return 2
         Send3270("Ascii(1,19,7)")
         If StringMid($status, 7, 7) = "ALREADY" Then Return 3
         Send3270("Ascii(5,42,7)")
         If StringMid($status, 7, 7) = "RESTART" Then
            Send3270("enter()")
            WaitFor(1, 33, 6, "ENABLE")
            Return 0
         EndIf
      ElseIf $tog = 2 Then
         Send3270("Ascii(13,23,6)")
         If StringMid($status, 7, 6) = "ENABLE" Then Return 0
         Send3270("Ascii(23,20,7)")
         If StringMid($status, 7, 7) = "ALREADY" Then Return 1
         Send3270("Ascii(23,31,9)")
         If StringMid($status, 7, 9) = "NOT FOUND" Then Return 2
      EndIf
   WEnd
   Return 4
EndFunc

Func StringEncrypt($bEncrypt, $sData, $sPassword = '*KEYREMOVED*')
   If $sData = "" Then Return ''
   _Crypt_Startup() ; Start the Crypt library.
   Local $sReturn = ''
   If $bEncrypt Then ; If the flag is set to True then encrypt, otherwise decrypt.
      $sReturn = _Crypt_EncryptData($sData, $sPassword, $CALG_RC4)
   Else
      $sReturn = BinaryToString(_Crypt_DecryptData($sData, $sPassword, $CALG_RC4))
   EndIf
   _Crypt_Shutdown() ; Shutdown the Crypt library.
   Return $sReturn
EndFunc   ;==>StringEncrypt

 

Edited by Aphotic
Link to comment
Share on other sites

  • 10 months later...
Emulator Name DLL Name HLLAPI Function Name Attachmate EXTRA! and Attachmate myEXTRA! Terminal Viewer   ehlapi32.dll     hllapi
Attachmate INFOConnect                                                                                  ihlapi32.dll    WinHLLAPI
Hummingbird HostExplorer                                                                                ehllap32.dll     HLLAPI32
IBM Personal Communications PCOM) and IBM WebSphere Host On-Demand                                      pcshll32.dll     hllapi
NetManage RUMBA and NetManage RUMBA Web-To-Host                                                        ehlapi32.dll      hllapi
PuTTY                                                                                                Not applicable     Not applicable
Seagull BlueZone                                                                                       WHLAPI32.dll     hllapi
WRQ Reflection                                                                                         hllapi32.dll     hllapi
Zephyr (PC/Web to Host)                                                                                 PassHll.dll     hllapi

To complete this post

Just lately I had to deal with a mainframe and mostly above dll's are installed to "talk" to the emulator. Little harder then the activeX object models but these are frequently not installed.

reading this http://www.ibm.com/support/knowledgecenter/SSEQ5Y_5.9.0/com.ibm.pcomm.doc/books/html/emulator_programming06.htm

and this http://www-03.ibm.com/systems/power/software/i/access/windows/toolkit/vb.html

then all knowledge together to do it from AutoIT 

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...