Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 如何在IBM主机访问库中使SendKeys同步运行_Vb.net_Com_Ibm Midrange_Terminal Emulator - Fatal编程技术网

Vb.net 如何在IBM主机访问库中使SendKeys同步运行

Vb.net 如何在IBM主机访问库中使SendKeys同步运行,vb.net,com,ibm-midrange,terminal-emulator,Vb.net,Com,Ibm Midrange,Terminal Emulator,我使用作为通过终端仿真器与IBMAS400(又称iSeries,IBMi,green screen,5250)通信的一种方式。我注意到,当您发出“SendKeys”指令时,在IBM emulator使用该命令完成之前,控制将返回到您的应用程序。这可能会导致计时问题,因为您可能会在系统准备接受另一条“SendKeys”指令之前发送该指令 例如: Imports AutPSTypeLibrary Imports AutConnListTypeLibrary Imports AutSessTypeLi

我使用作为通过终端仿真器与IBMAS400(又称iSeries,IBMi,green screen,5250)通信的一种方式。我注意到,当您发出“SendKeys”指令时,在IBM emulator使用该命令完成之前,控制将返回到您的应用程序。这可能会导致计时问题,因为您可能会在系统准备接受另一条“SendKeys”指令之前发送该指令

例如:

Imports AutPSTypeLibrary
Imports AutConnListTypeLibrary
Imports AutSessTypeLibrary

Sub Example
    Dim connections As New AutConnList
    connections.Refresh()
    If connections.Count < 1 Then Throw New InvalidOperationException("No AS400 screen can currently be found.")
    Dim connection As IAutConnInfo = DirectCast(connections(1), IAutConnInfo)

    _Session = New AutSess2
    _Session.SetConnectionByHandle(connection.Handle)
    Dim _Presentation As AutPS = DirectCast(_Session.autECLPS, AutPS)
    _Presentation.SendKeys("PM70[enter]", 22, 8)
    _Presentation.SendKeys("ND71221AD[enter]", 22, 20)

End Sub
导入AUTPSTYPE库
导入列表类型库
进口自动化图书馆
子示例
将连接设置为新的AUTCONLIST
connections.Refresh()
如果connections.Count<1,则抛出新的InvalidOperationException(“当前找不到AS400屏幕”)
作为IAutConnInfo=DirectCast的Dim连接(连接(1),IAutConnInfo)
_会话=新的autses2
_Session.SetConnectionByHandle(connection.Handle)
Dim _表示为AutPS=DirectCast(_Session.autECLPS,AutPS)
_演示文稿。发送键(“PM70[输入]”,22,8)
_Presentation.SendKeys(“ND71221AD[enter]”,22,20)
端接头
在调试程序中单步执行代码时将正常工作,但在正常运行时将失败,因为第二条指令发送得太快

处理这个问题的一种方法是在每个命令后放置一个计时器或循环,以降低调用程序的速度。我认为这不太理想,因为时间的长短并不总是可以预测的,你会经常等待更长的时间来适应偶尔的打嗝。这会减慢整个进程的运行时间

解决此问题的另一种方法是等待屏幕上出现可测试的条件,作为发送命令的结果。这有时会起作用,但某些命令不会导致测试屏幕更改,如果您希望将命令调用抽象到类或子例程中,则必须传递要监视的屏幕条件

我想找到一种在一般情况下有效的“等待”方法。像autECLScreenDesc类这样的选项似乎必须根据非常特定的条件进行定制

autECLPS(又名AutPS)类有许多等待方法(Wait、WaitForCursor、WaitWhileCursor、WaitForString、WaitWhileString、waitforstringinct、WaitWhileString、waitforstrib、WaitForScreen、WaitWhileScreen)但它们似乎也在等待特定条件,不适用于一般情况。一般情况下,它对我很重要,因为我实际上正在尝试编写一个通用字段更新子例程,它可以从.dll内外的许多地方调用

这个例子是用VB.NET编写的,但是我希望C语言、C++、VB6、java都有相同的行为。实际上,任何使用IBM的“Operator Information Area”类的东西似乎都能为这个问题提供解决方案

我的一般情况似乎与此实现正确配合:

 Friend Sub PutTextWithEnter(ByVal field As FieldDefinition, ByVal value As String)
    If IsNothing(field) Then Throw New ArgumentNullException("field")
    If IsNothing(value) Then Throw New ArgumentNullException("value")
    _Presentation.SendKeys(Mid(value.Trim, 1, field.Length).PadRight(field.Length) & "[enter]", field.Row, field.Column)
    WaitForEmulator(_Session.Handle)
End Sub

Private Sub WaitForEmulator(ByVal EmulatorHandle As Integer)
    Dim Oia As New AutOIATypeLibrary.AutOIA
    Oia.SetConnectionByHandle(EmulatorHandle)
    Oia.WaitForInputReady()
    Oia.WaitForAppAvailable()
End Sub
我要感谢一位名为“khieyzer”的用户,他为我们指出了这一干净的通用解决方案

编辑:

经过几周的调试和解决时间和资源释放问题后,此方法现在的内容如下:

Private Sub WaitForEmulator(ByRef NeededReset As Boolean)
    Dim Oia As New AutOIA
    Oia.SetConnectionByHandle(_Presentation.Handle)

    Dim inhibit As InhibitReason = Oia.InputInhibited
    If inhibit = InhibitReason.pcOtherInhibit Then
        _Presentation.SendKeys("[reset]")
        NeededReset = True
        WaitForEmulator(NeededReset)
        Marshal.ReleaseComObject(Oia)
        Exit Sub
    End If

    If Not Oia.WaitForInputReady(6000) Then
        If Oia.InputInhibited = InhibitReason.pcOtherInhibit Then
            _Presentation.SendKeys("[reset]")
            NeededReset = True
            WaitForEmulator(NeededReset)
            Marshal.ReleaseComObject(Oia)
            Exit Sub
        Else
            Marshal.ReleaseComObject(Oia)
            Throw New InvalidOperationException("The system has stopped responding.")
        End If
    End If

    Oia.WaitForInputReady()
    Oia.WaitForAppAvailable()
    Marshal.ReleaseComObject(Oia)
End Sub

IBM中端计算机(包括AS/400及其后续产品)的绿屏终端不是3270,而是5250。3270用于IBM大型机(根据维基百科,从System/370开始)。@JohnY你说得对。我把终端的名字划掉了,因为这家公司既有一个使用3270(几年前我编写了屏幕抓取包装器)的基于CICS的旧IBM系统,也有AS400(我们最近通过合并获得)。我将把这个问题更新为5250。