/// <summary> /// Waits for the specified text to appear at the specified location. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="text"></param> /// <param name="timeoutMS"></param> /// <returns></returns> public bool WaitForText(int x, int y, string text, int timeoutMS) { if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } var start = DateTime.Now.Ticks; //bool ok = false; if (Config.AlwaysRefreshWhenWaiting) { lock (this) { DisposeOfCurrentScreenXML(); currentScreenXML = null; } } do { if (CurrentScreenXML != null) { var screenText = CurrentScreenXML.GetText(x, y, text.Length); if (screenText == text) { if (Audit != null) { Audit.WriteLine("WaitForText('" + text + "') Found!"); } return(true); } } // if (timeoutMS == 0) { if (Audit != null) { Audit.WriteLine("WaitForText('" + text + "') Not found"); } return(false); } // Thread.Sleep(100); if (Config.AlwaysRefreshWhenWaiting) { lock (this) { DisposeOfCurrentScreenXML(); currentScreenXML = null; } } Refresh(true, 1000); } while ((DateTime.Now.Ticks - start) / 10000 < timeoutMS); // if (Audit != null) { Audit.WriteLine("WaitForText('" + text + "') Timed out"); } return(false); }
public void Refresh() { lock (this) { _currentScreenXML = null; } }
/// <summary> /// Refreshes the connection to the mainframe. /// </summary> public void Refresh() { lock (this) { DisposeOfCurrentScreenXML(); currentScreenXML = null; } }
// // /// <summary> /// Constructor for TNEmulator /// </summary> public TNEmulator() { _currentScreenXML = null; // currentConnection = null; // // this.mConnectionConfiguration = new ConnectionConfig(); // }
/// <summary> /// Send text to screen /// </summary> /// <param name="text"></param> public bool SendText(string text) { if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } lock (this) { _currentScreenXML = null; } return(currentConnection.ExecuteAction(false, "String", text)); }
private void currentConnection_RunScriptEvent(string where) { lock (this) { _currentScreenXML = null; if (sout != null && Debug) { sout.WriteLine("mre.Release(1) from location " + where); } mre.Release(1); } }
/// <summary> /// Identification exception /// </summary> /// <param name="page">The page we're coming from (not the page we're on!)</param> /// <param name="screen">The IXMLScreen object for the screen that we couldn't recognize</param> public TNIdentificationException(string page, IXMLScreen screen) { mPage = page; if (screen == null) { mDump = null; } else { mDump = screen.Dump(); } }
protected void DisposeOfCurrentScreenXML() { if (currentScreenXML != null) { IDisposable disposeXML = currentScreenXML as IDisposable; if (disposeXML != null) { disposeXML.Dispose(); } currentScreenXML = null; } }
/// <summary> /// Wait for some text to appear at the specified location /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="text"></param> /// <param name="timeoutMS"></param> /// <returns></returns> public bool WaitForText(int x, int y, string text, int timeoutMS) { if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } long start = DateTime.Now.Ticks; //bool ok = false; if (Config.AlwaysRefreshWhenWaiting) { lock (this) { this._currentScreenXML = null; } } do { if (CurrentScreenXML != null) { string screenText = CurrentScreenXML.GetText(x, y, text.Length); if (screenText == text) { return(true); } } // if (timeoutMS == 0) { return(false); } // System.Threading.Thread.Sleep(100); if (Config.AlwaysRefreshWhenWaiting) { lock (this) { this._currentScreenXML = null; } } Refresh(true, 1000); }while (((DateTime.Now.Ticks - start) / 10000) < timeoutMS); // return(false); }
/// <summary> /// Set field value. /// </summary> /// <param name="index"></param> /// <param name="text"></param> public void SetField(int index, string text) { if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } if (index == -1001) { switch (text) { case "showparseerror": currentConnection.ShowParseError = true; return; default: return; } } currentConnection.ExecuteAction(false, "FieldSet", index, text); _currentScreenXML = null; }
/// <summary> /// Waits for the specified text to appear at the specified location. /// </summary> /// <param name="timeoutMS"></param> /// <param name="text"></param> /// <returns>Index of text on screen, -1 if not found or timeout occurs</returns> public int WaitForTextOnScreen(int timeoutMS, params string[] text) { if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } long start = DateTime.Now.Ticks; //bool ok = false; if (Config.AlwaysRefreshWhenWaiting) { lock (this) { DisposeOfCurrentScreenXML(); this.currentScreenXML = null; } } do { lock (this) { if (CurrentScreenXML != null) { int index = CurrentScreenXML.LookForTextStrings(text); if (index != -1) { if (Audit != null) { Audit.WriteLine("WaitForText('" + text[index] + "') Found!"); } return(index); } } } // if (timeoutMS > 0) { // System.Threading.Thread.Sleep(100); if (Config.AlwaysRefreshWhenWaiting) { lock (this) { DisposeOfCurrentScreenXML(); this.currentScreenXML = null; } } Refresh(true, 1000); } }while (timeoutMS > 0 && ((DateTime.Now.Ticks - start) / 10000) < timeoutMS); // if (Audit != null) { string temp = ""; foreach (string t in text) { temp += "t" + "//"; } Audit.WriteLine("WaitForText('" + temp + "') Timed out"); } return(-1); }
public TNEmulator() { currentScreenXML = null; currentConnection = null; this.mConnectionConfiguration = new ConnectionConfig(); }
/// <summary> /// Connect to TN3270 server using the connection details specified. /// </summary> /// <remarks> /// You should set the Audit property to an instance of an object that implements /// the IAudit interface if you want to see any debugging information from this function /// call. /// </remarks> /// <param name="host">Host name or IP address. Mandatory</param> /// <param name="port">TCP/IP port to connect to (default TN3270 port is 23)</param> /// <param name="lu">TN3270E LU to connect to. Specify null for no LU.</param> public void Connect(string host, int port, string lu) { if (this.currentConnection != null) { this.currentConnection.Disconnect(); this.currentConnection.CursorLocationChanged -= currentConnection_CursorLocationChanged; } try { semaphore.Reset(); this.currentConnection = null; this.currentConnection = new TN3270API(); this.currentConnection.Debug = debug; this.currentConnection.RunScriptRequested += new RunScriptDelegate(currentConnection_RunScriptEvent); this.currentConnection.CursorLocationChanged += currentConnection_CursorLocationChanged; this.currentConnection.Disconnected += apiOnDisconnectDelegate; this.apiOnDisconnectDelegate = new OnDisconnectDelegate(currentConnection_OnDisconnect); // // Debug out our current state // if (sout != null) { sout.WriteLine("Open3270 emulator version " + Assembly.GetAssembly(typeof(Open3270.TNEmulator)).GetName().Version + " (c) 2004-2017 Mike Warriner and many others"); #if false sout.WriteLine("(c) 2004-2006 Mike Warriner ([email protected]). All rights reserved"); sout.WriteLine(""); sout.WriteLine("This is free software; you can redistribute it and/or modify it"); sout.WriteLine("under the terms of the GNU Lesser General Public License as"); sout.WriteLine("published by the Free Software Foundation; either version 2.1 of"); sout.WriteLine("the License, or (at your option) any later version."); sout.WriteLine(""); sout.WriteLine("This software is distributed in the hope that it will be useful,"); sout.WriteLine("but WITHOUT ANY WARRANTY; without even the implied warranty of"); sout.WriteLine("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"); sout.WriteLine("Lesser General Public License for more details."); sout.WriteLine(""); sout.WriteLine("You should have received a copy of the GNU Lesser General Public"); sout.WriteLine("License along with this software; if not, write to the Free"); sout.WriteLine("Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA"); sout.WriteLine("02110-1301 USA, or see the FSF site: http://www.fsf.org."); sout.WriteLine(""); #endif if (firstTime) { firstTime = false; } if (Debug) { Config.Dump(sout); sout.WriteLine("Connect to host \"" + host + "\""); sout.WriteLine(" port \"" + port + "\""); sout.WriteLine(" LU \"" + lu + "\""); sout.WriteLine(" Local IP \"" + _localIP + "\""); } } else { } currentConnection.UseSSL = this.mUseSSL; /// Modified CFCJR Feb/29/2008 to support local IP endpoint if (!string.IsNullOrEmpty(_localIP)) { currentConnection.Connect(this.sout, _localIP, host, port, this.mConnectionConfiguration); } else { currentConnection.Connect(this.sout, host, port, lu, this.mConnectionConfiguration); } currentConnection.WaitForConnect(-1); DisposeOfCurrentScreenXML(); currentScreenXML = null; // Force refresh // GetScreenAsXML(); } catch (Exception) { currentConnection = null; throw; } // These don't close the connection try { this.mScreenName = "Start"; Refresh(true, 10000); if (sout != null && Debug == true) { sout.WriteLine("Debug::Connected"); } //mScreenProcessor.Update_Screen(currentScreenXML, true); } catch (Exception) { throw; } return; }
/// <summary> /// Refresh the current screen. If timeout > 0, it will wait for /// this number of milliseconds. /// If waitForValidScreen is true, it will wait for a valid screen, otherwise it /// will return immediately that any screen data is visible /// </summary> /// <param name="waitForValidScreen"></param> /// <param name="timeoutMS">The time to wait in ms</param> /// <returns></returns> public bool Refresh(bool waitForValidScreen, int timeoutMS) { long start = DateTime.Now.Ticks / (10 * 1000); long end = start + timeoutMS; if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } if (sout != null && Debug == true) { sout.WriteLine("Refresh::Refresh(" + waitForValidScreen + ", " + timeoutMS + "). FastScreenMode=" + this.mConnectionConfiguration.FastScreenMode); } do { if (waitForValidScreen) { bool run = false; int timeout = 0; do { timeout = (int)(end - (DateTime.Now.Ticks / 10000)); if (timeout > 0) { if (sout != null && this.Debug) { sout.WriteLine("Refresh::Acquire(" + timeout + " milliseconds). unsafe Count is currently " + semaphore.Count); } run = semaphore.Acquire(Math.Min(timeout, 1000)); if (!IsConnected) { throw new TNHostException("The TN3270 connection was lost", this.currentConnection.DisconnectReason, null); } if (run) { if (sout != null && this.Debug) { sout.WriteLine("Refresh::return true at line 279"); } return(true); } else { } } }while (!run && timeout > 0); if (sout != null && this.Debug) { sout.WriteLine("Refresh::Timeout or acquire failed. run= " + run + " timeout=" + timeout); } } if (this.mConnectionConfiguration.FastScreenMode || this.KeyboardLocked == 0) { // Store screen in screen database and identify it this.DisposeOfCurrentScreenXML(); // Force a refresh currentScreenXML = null; if (sout != null && this.Debug) { sout.WriteLine("Refresh::Timeout, but since keyboard is not locked or fastmode=true, return true anyway"); } return(true); } else { System.Threading.Thread.Sleep(10); } }while (DateTime.Now.Ticks / 10000 < end); if (sout != null) { sout.WriteLine("Refresh::Timed out (2) waiting for a valid screen. Timeout was " + timeoutMS); } if (Config.FastScreenMode == false && Config.ThrowExceptionOnLockedScreen && this.KeyboardLocked != 0) { throw new ApplicationException("Timeout waiting for new screen with keyboard inhibit false - screen present with keyboard inhibit. Turn off the configuration option 'ThrowExceptionOnLockedScreen' to turn off this exception. Timeout was " + timeoutMS + " and keyboard inhibit is " + this.KeyboardLocked); } if (Config.IdentificationEngineOn) { throw new TNIdentificationException(mScreenName, GetScreenAsXML()); } else { return(false); } }
/// <summary> /// Sends the specified key stroke to the emulator. /// </summary> /// <param name="waitForScreenToUpdate"></param> /// <param name="key"></param> /// <param name="timeout"></param> /// <returns></returns> public bool SendKey(bool waitForScreenToUpdate, TnKey key, int timeout) { bool triggerSubmit = false; bool success = false; string command; //This is only used as a parameter for other methods when we're using function keys. //e.g. F1 yields a command of "PF" and a functionInteger of 1. int functionInteger = -1; if (sout != null && Debug == true) { sout.WriteLine("SendKeyFromText(" + waitForScreenToUpdate + ", \"" + key.ToString() + "\", " + timeout + ")"); } if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } //Get the command name and accompanying int parameter, if applicable if (Constants.FunctionKeys.Contains(key)) { command = "PF"; functionInteger = Constants.FunctionKeyIntLUT[key]; } else if (Constants.AKeys.Contains(key)) { command = "PA"; functionInteger = Constants.FunctionKeyIntLUT[key]; } else { command = key.ToString(); } //Should this action be followed by a submit? triggerSubmit = this.Config.SubmitAllKeyboardCommands || this.currentConnection.KeyboardCommandCausesSubmit(command); if (triggerSubmit) { lock (this) { this.DisposeOfCurrentScreenXML(); currentScreenXML = null; if (sout != null && Debug) { sout.WriteLine("mre.Reset. Count was " + semaphore.Count); } // Clear to initial count (0) semaphore.Reset(); } } success = this.currentConnection.ExecuteAction(triggerSubmit, command, functionInteger); if (sout != null && Debug) { sout.WriteLine("SendKeyFromText - submit = " + triggerSubmit + " ok=" + success); } if (triggerSubmit && success) { // Wait for a valid screen to appear if (waitForScreenToUpdate) { success = this.Refresh(true, timeout); } else { success = true; } } return(success); }
public bool SendKeyFromText(bool waitForScreenToUpdate, string text, int timeout) { bool submit = false; bool success = false; if (sout != null && Debug == true) { sout.WriteLine("SendKeyFromText(" + waitForScreenToUpdate + ", \"" + text + "\", " + timeout + ")"); } if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } if (text.Length < 2) { // No keys are less than 2 characters. return(false); } if (this.Config.SubmitAllKeyboardCommands) { submit = true; } else { if (text.Substring(0, 2) == "PF") { submit = this.currentConnection.KeyboardCommandCausesSubmit("PF"); } else if (text.Substring(0, 2) == "PA") { submit = this.currentConnection.KeyboardCommandCausesSubmit("PA"); } else { submit = this.currentConnection.KeyboardCommandCausesSubmit(text); } } if (submit) { lock (this) { this.DisposeOfCurrentScreenXML(); currentScreenXML = null; if (sout != null && Debug) { sout.WriteLine("mre.Reset. Count was " + semaphore.Count); } { // Clear to initial count (0) semaphore.Reset(); } } } if (text.Substring(0, 2) == "PF") { success = this.currentConnection.ExecuteAction(submit, "PF", System.Convert.ToInt32(text.Substring(2, 2))); } else if (text.Substring(0, 2) == "PA") { success = this.currentConnection.ExecuteAction(submit, "PA", System.Convert.ToInt32(text.Substring(2, 2))); } else { success = this.currentConnection.ExecuteAction(submit, text); } if (sout != null && Debug) { sout.WriteLine("SendKeyFromText - submit = " + submit + " ok=" + success); } if (submit && success) { // Wait for a valid screen to appear if (waitForScreenToUpdate) { return(Refresh(true, timeout)); } else { return(true); } } else { return(success); } }
/// <summary> /// Sends a key to the host. Key names are: /// Attn, Backspace,BackTab,CircumNot,Clear,CursorSelect,Delete,DeleteField, /// DeleteWord,Down,Dup,Enter,Erase,EraseEOF,EraseInput,FieldEnd, /// FieldMark,FieldExit,Home,Insert,Interrupt,Key,Left,Left2,Newline,NextWord, /// PAnn, PFnn, PreviousWord,Reset,Right,Right2,SysReq,Tab,Toggle,ToggleInsert,ToggleReverse,Up /// </summary> /// <param name="WaitForScreenToUpdate"></param> /// <param name="text">Key to send</param> /// <param name="timeout">Timeout in seconds</param> /// <returns></returns> public bool SendKeyFromText(bool WaitForScreenToUpdate, string text, int timeout) { if (sout != null && Debug == true) { sout.WriteLine("SendKeyFromText(" + WaitForScreenToUpdate + ", \"" + text + "\", " + timeout + ")"); } // if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } // if (text.Length < 2) { return(false); // no keys are less than 2 characters. } // bool submit = false; if (Config.SubmitAllKeyboardCommands) { submit = true; } else { if (text.Substring(0, 2) == "PF") { submit = this.currentConnection.KeyboardCommandCausesSubmit("PF", System.Convert.ToInt32(text.Substring(2, 2))); } else if (text.Substring(0, 2) == "PA") { submit = this.currentConnection.KeyboardCommandCausesSubmit("PA", System.Convert.ToInt32(text.Substring(2, 2))); } else { submit = this.currentConnection.KeyboardCommandCausesSubmit(text); } } bool ok = false; if (submit) { lock (this) { _currentScreenXML = null; if (sout != null && Debug) { sout.WriteLine("mre.AcquireAll. Count was " + mre.Count); } mre.AcquireAll(0); } // } // if (text.Substring(0, 2) == "PF") { ok = this.currentConnection.ExecuteAction(submit, "PF", System.Convert.ToInt32(text.Substring(2, 2))); } else if (text.Substring(0, 2) == "PA") { ok = this.currentConnection.ExecuteAction(submit, "PA", System.Convert.ToInt32(text.Substring(2, 2))); } else { ok = this.currentConnection.ExecuteAction(submit, text); } if (sout != null && Debug == true) { sout.WriteLine("SendKeyFromText - submit = " + submit + " ok=" + ok); } if (submit && ok) { // wait for a valid screen to appear if (WaitForScreenToUpdate) { return(Refresh(true, timeout)); } else { return(true); } } else { return(ok); } }
/// <summary> /// Refresh the current screen. If timeout > 0, it will wait for /// this number of milliseconds. /// If waitForValidScreen is true, it will wait for a valid screen, otherwise it /// will return immediately that any screen data is visible /// </summary> /// <param name="waitForValidScreen"></param> /// <param name="timeoutMS">The time to wait in ms</param> /// <returns></returns> public bool Refresh(bool waitForValidScreen, int timeoutMS) { long start = DateTime.Now.Ticks / (10 * 1000); long end = start + timeoutMS; // timeout if (currentConnection == null) { throw new TNHostException("TNEmulator is not connected", "There is no currently open TN3270 connection", null); } if (sout != null && Debug == true) { sout.WriteLine("Refresh::Refresh(" + waitForValidScreen + ", " + timeoutMS + "). FastScreenMode=" + this.mConnectionConfiguration.FastScreenMode); } do { if (waitForValidScreen) { bool run = false; int timeout = 0; do { timeout = (int)(end - (DateTime.Now.Ticks / 10000)); if (timeout > 0) { if (sout != null && this.Debug) { sout.WriteLine("Refresh::Acquire(" + timeout + " milliseconds). unsafe Count is currently " + mre.Count); } run = mre.Acquire(Math.Min(timeout, 1000)); //Console.WriteLine("run = "+run); if (!IsConnected) { throw new TNHostException("The TN3270 connection was lost", this.currentConnection.DisconnectReason, null); } if (run) { if (sout != null && this.Debug) { sout.WriteLine("Refresh::return true at line 279"); } return(true); } } }while (!run && timeout > 0); if (sout != null && this.Debug) { sout.WriteLine("Refresh::Timeout or acquire failed. run= " + run + " timeout=" + timeout); } } if (this.mConnectionConfiguration.FastScreenMode || this.KeyboardLocked == 0) { // // Store screen in screen database and identify it // _currentScreenXML = null; // force a refresh if (sout != null && this.Debug) { sout.WriteLine("Refresh::Timeout, but since keyboard is not locked and fastmode=true, return true anyway"); } return(true); // // --Screen identification code here-- // #if FALSE if (waitForValidScreen) { if (sout != null) { sout.WriteLine("Refresh::waitForValidScreen is true - loop will loop and acquire another mre lock."); } // reset screen count to let us then wait for the next transition // wait for the next screen transistion //Console.WriteLine("-- acquire(0), release any pending transactions"); //mre.AcquireAll(0); //mre.Reset(); } else { if (sout != null && this.Debug == true) { sout.WriteLine("waitForValidScreen is false. Refresh returned false."); } return(false); } #endif } else { System.Threading.Thread.Sleep(10); } }while (DateTime.Now.Ticks / 10000 < end); // // if (sout != null) { sout.WriteLine("Refresh::Timed out (2) waiting for a valid screen. Timeout was " + timeoutMS); } if (Config.FastScreenMode == false && Config.ThrowExceptionOnLockedScreen && this.KeyboardLocked != 0) { throw new ApplicationException("Timeout waiting for new screen with keyboard inhibit false - screen present with keyboard inhibit. Turn off the configuration option 'ThrowExceptionOnLockedScreen' to turn off this exception. Timeout was " + timeoutMS + " and keyboard inhibit is " + this.KeyboardLocked); } if (Config.IdentificationEngineOn) { throw new TNIdentificationException(mScreenName, GetScreenAsXML()); } else { return(false); } }
/// <summary> /// Connect to TN3270 server using the connection details specified. /// </summary> /// <remarks> /// You should set the Audit property to an instance of an object that implements /// the IAudit interface if you want to see any debugging information from this function /// call. /// </remarks> /// <param name="host">Host name or IP address. Mandatory</param> /// <param name="port">TCP/IP port to connect to (default TN3270 port is 23)</param> /// <param name="lu">TN3270E LU to connect to. Specify null for no LU.</param> public void Connect(string host, int port, string lu) { if (currentConnection != null) { currentConnection.Disconnect(); } // // try { mre.Reset(); currentConnection = null; currentConnection = new TN3270API(); currentConnection.Debug = mDebug; currentConnection.RunScriptEvent += new RunScriptDelegate(currentConnection_RunScriptEvent); apiOnDisconnectDelegate = new OnDisconnectDelegate(currentConnection_OnDisconnect); currentConnection.OnDisconnect += apiOnDisconnectDelegate; // // Debug out our current state // if (sout != null) { sout.WriteLine("Open3270 emulator version " + Assembly.GetAssembly(typeof(Open3270.TNEmulator)).GetName().Version); sout.WriteLine("(c) 2004-2006 Mike Warriner ([email protected]). All rights reserved"); sout.WriteLine(""); // if (mFirstTime) { mFirstTime = false; } if (Debug) { Config.Dump(sout); sout.WriteLine("Connect to host \"" + host + "\""); sout.WriteLine(" port \"" + port + "\""); sout.WriteLine(" LU \"" + lu + "\""); sout.WriteLine(" Local IP \"" + _localIP + "\""); } } else { } // currentConnection.UseSSL = this.mUseSSL; // /// Modified CFCJR Feb/29/2008 to support local IP endpoint if (!string.IsNullOrEmpty(_localIP)) { currentConnection.Connect(this.sout, _localIP, host, port, this.mConnectionConfiguration); } else { currentConnection.Connect(this.sout, host, port, lu, this.mConnectionConfiguration); } // // // currentConnection.WaitForConnect(-1); DisposeOfCurrentScreenXML(); _currentScreenXML = null; // force refresh // GetScreenAsXML(); } catch (Exception) { currentConnection = null; throw; } // these don't close the connection try { this.mScreenName = "Start"; Refresh(true, 40000); if (sout != null && Debug == true) { sout.WriteLine("Debug::Connected"); } //mScreenProcessor.Update_Screen(currentScreenXML, true); } catch (Exception) { throw; } return; }
public TNEmulator() { currentScreenXML = null; currentConnection = null; Config = new ConnectionConfig(); }