An Improved Host Command for Windows

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

One of the functions provided with Client Access/400 is the Host Command program. After installing the Windows client, the Host Command program is in your Client Access/400 program group. When you run Host Command, you are prompted to enter the AS/400 command that you want to run. The command is then submitted to the default system.

The Host Command program, as provided, works in a peculiar manner. After entering the command to run, another window is displayed. The other window is apparently a DOS box, in which the command is running. Although error and completion messages are output from the Host Command, you probably won’t see them, as the DOS box closes immediately after displaying the messages.

As an alternative, you can create your own version of the Host Command function using the Client Access/400 APIs. The program shown here uses Visual Basic. By creating this version of the Host Command program, you’ll not only have a better version of the function, but you’ll also see how to use the Submit Remote Command APIs. If you develop Windows programs using Visual Basic, there may be times when you need to use the submit remote command function within those programs. You can modify the code shown here as needed. Features of the Submit Remote Command Program

The Submit Remote Command program provides some helpful improvements to the Client Access/400 Host Command program. Figure 1 shows the Submit Remote Command dialog with each of its elements labeled.

You choose the AS/400 system to which the command is submitted from a list of AS/400s to which you have router sessions. The default system is the first entry in the list. The list is shown in the lstSystemName control.


After submitting a command, a status message is shown at the bottom of the window. The status message is in the lblMessageLine control. The status message is sent for either successful or unsuccessful completion of the command.

Finally, you can review all of the messages that were sent as a result of running the command. You review messages by clicking the cmdShowMessages control. Figure 2 shows a sample of the messages sent for the erroneous WRKOUQT command. Figure 3 shows a sample of a successful command.

Program Requirements

You need only a few things to create this program. First, you need the Client Access/400 for Windows 3.1 software. Verify that you have two files, EHNAPPC.DLL and EHNSRW.DLL, installed on your PC. Those files will probably be in your CAWIN directory or your WINDOWSSYSTEM directory. The files contain the code needed for the Client Access/400 APIs.

You’ll also need Visual Basic. I created and tested the program with Visual Basic 3.0 for Windows. Although you’ll want the Professional Version for most projects involving AS/400 client/server programming, you can create the Submit Remote Command program with the Standard Version.

Finally, you’ll need to create the Submit Remote Command form and enter the source code. Use Figure 1 as a guide for creating the form. You need to create module RMTCMD.BAS (Figure 4) and RMTCMD.FRM (Figures 5 through 9). The code for this project is also available on the Midrange Computing BBS system, in file area 2. The BBS number is listed on page 2 of this issue.

How the Program Works

The APIs are declared in the RMTCMD.BAS module (Figure 4). The program uses two APPC APIs and three Remote Command APIs. These are:

EHNAPPC_IsRouterLoaded—to verify that the Client Access/ 400 router is loaded.

EHNAPPC_QuerySystems—to get the list of systems to which the router is connected, and the name of the default system.

EHNSR_SubmitCommand—to submit the remote command to the system that you choose.

EHNSR_GetMessage—to get the messages returned as a result of submitting the command.

EHNSR_StopConversation—to stop the APPC conversation used by the Submit Command APIs.

Visual Basic requires the API function declarations so that it can find the function code (in either the EHNAPPC.DLL or EHNSRW.DLL files), and so that it knows how to work with the parameters.

The RMTCMD.BAS module also includes declarations for other fields and constants used in the program.

When you start the program, the code shown in the Form_Load (Figure 5) is executed. This routine checks for an active router connection. If the router is not active, a


message box is displayed and the program ends. Next, the routine gets the list of systems to which the router is connected. After getting the list, it picks each system name out of the list, and puts the names into a Visual Basic drop-down list box. You choose the system to which the command is sent from the list box.

After typing in a command, you click the Submit Command button. That runs the code in the cmdSubmit_Click routine (Figure 6). If you didn’t enter a command, a message box is displayed telling you that a blank command can not be submitted. If you did enter some characters, the routine strips out any trailing control characters (e.g., carriage return, line feed). If trailing control characters are not removed, the AS/400 rejects the command.

The routine then submits the command to the AS/400. When you submit the command, you also provide a reply message buffer. Any error or status messages go into the reply buffer. The messages do not include inquiry messages, as there is no way to respond to a message in the reply buffer.

After running the submit command API, cmdSubmit_Click checks the return code from the API. Depending on the return code, a message is displayed on the form. The Show Messages command button is also enabled to let you look at messages from the reply buffer.

The code in cmdShowMessages_Click (Figure 7) runs when you click the Show Messages button. This routine retrieves messages from the reply buffer, formats them, and displays them in a Visual Basic message box. The submit remote command API can put up to 10 reply messages into the message buffer. The cmdShowMessages_Click routine loops through the reply buffer until there are no more messages to retrieve from the buffer.

If you submit more than one command, the txtCommand_Change routine (Figure 8) runs whenever you type in a new command. This routine disables the Show Messages command button. You cannot click the button until after submitting the new command.

Finally, the program ends when you click the Exit button. The cmdExit_Click routine runs (Figure 9). The routine calls the Stop Conversation API to free the resources used by the Submit Command function, then ends the Visual Basic program.

References

The Submit Remote Command API and the APPC APIs used in this program are documented in IBM’s Client Access/400 for Windows 3.1 API and Technical Reference manual (SC41-3531). The documentation describes each API function, and also the return codes and error conditions associated with each API.


An_Improved_Host_Command_for_Windows04-00.jpg 598x290

Figure 1: The Submit Remote Command Dialog

An_Improved_Host_Command_for_Windows04-01.jpg 450x208

Figure 2: MsgBox to Display Error Messages

An_Improved_Host_Command_for_Windows04-02.jpg 450x198

Figure 3: MsgBox, Successful Command Completion

Option Explicit
'declare APPC (router) functions
Declare Function EHNAPPC_IsRouterLoaded Lib "EHNAPPC.DLL" (ByVal hWnd As Integer) As Integer
Declare Function EHNAPPC_QuerySystems Lib "EHNAPPC.DLL" (ByVal hWnd As Integer,
lpSysCount As Integer, ByVal lpSys As String) As Integer
'declare Submit Remote Command functions


Declare Function EHNSR_GetMessage Lib "EHNSRW.DLL" (ByVal hWnd As Integer,

ByVal szSysName As String, lpwSevCode As Integer, ByVal szMsgID As String,
ByVal szMsg As String, ByVal wMsgLen As Integer, ByVal szMsgBuf As String,
ByVal lpwMsgBufLen As Integer) As Integer
Declare Function EHNSR_StopConversation Lib "EHNSRW.DLL" (ByVal hWnd As Integer,

ByVal szSysName As String) As Integer
Declare Function EHNSR_SubmitCommand Lib "EHNSRW.DLL" ( ByVal hWnd As Integer,

ByVal szSysName As String, ByVal szCommand As String, ByVal szMsgBuf As String,
ByVal wMsgBufLen As Integer, ByVal lpProcCallBack As Long) As Integer
'return codes for APPC and Submit Remote Command functions
Global Const EHNAPPC_OK = &H0
Global Const EHNSR_OK = &H0
'global constants for Visual Basic
Global Const MB_OK = 0 'display OK button
Global Const MB_ICONSTOP = 16 'STOP icon
Global Const MB_ICONINFORMATION = 64 'INFORMATION icon
Global Const DEFAULT = 0 'default mouse pointer
Global Const HOURGLASS = 11 'hourglass mouse pointer
Global Const BLUE = &HFF0000 'blue color
Global Const RED = &HFF 'red color
'other global variables and constants
Global gblSystemList As String * 320 'list of systems connected to
Global gblSystemName As String 'system name
Global Const gblMsgBufferLength = 1000 'message buffer length
Global gblMsgBuffer As String * gblMsgBufferLength Sub Form_Load ()

Dim I As Integer 'loop counter

Dim StartPos As Integer 'position in SystemList

Dim SystemCount As Integer 'number of systems connected to

'check for router loaded - MsgBox if not

If EHNAPPC_IsRouterLoaded(hWnd) = False Then

MsgBox "The Client Access/400 Router is not loaded.", MB_OK + MB_ICONSTOP,

"Router Not Loaded"

End

End If

'get list of systems router is connected to, pick out default for combo box

If Not EHNAPPC_OK = EHNAPPC_QuerySystems(hWnd, SystemCount, gblSystemList) Then

MsgBox "Error occurred on QuerySystems API.", MB_OK + MB_ICONSTOP,

"Query Systems Error"

End

End If

'get system names, put in list box

StartPos = 1

For I = 1 To SystemCount

lstSystemName.AddItem Mid$(gblSystemList, StartPos, 8) 'SysName is 8 chars

StartPos = StartPos + 10 'but API returns names of length 10

Next I

lstSystemName.ListIndex = 0 'set default system in list box

cmdShowMessages.Enabled = False 'start with Show Messages disabled

End Sub Sub cmdSubmit_Click ()

Dim APIReturnCode As Integer 'return code

Dim I As Integer 'loop control

'no processing if blank command entered

If txtCommand = "" Then
lblMessageLine = "Blank command not submitted."
lblMessageLine.ForeColor = RED
Exit Sub

End If

'trim all trailing characters after command string (CR, LF, etc.)

For I = 1 To Len(txtCommand)

If Mid(txtCommand, I, 1)

Figure 4: Module RMTCMD.BAS 'message buffer

Figure 5: The Form_Load Subroutine in RMTOMD.FRM


txtCommand = Mid(txtCommand, 1, I -1)

Exit For

End If

Next I

‘initialize for Submit processing

gblMsgBuffer = Space$(gblMsgBufferLength) ‘clear out buffer

Screen.MousePointer = HOURGLASS ‘set pointer - long wait

APIReturnCode = EHNSR_SubmitCommand(hWnd, gblSystemName, txtCommand,

gblMsgBuffer, gblMsgBufferLength, 0)

Screen.MousePointer = DEFAULT ’restore mouse

‘display status message line

If APIReturnCode = EHNSR_OK Then

lblMessageLine = “Command submitted sccessfully.”

lblMessageLine.ForeColor = BLUE

Else

lblMessageLine = “Error on submitted command.”

lblMessageLine.ForeColor = RED

End If

‘enable Show Messages button for message review

cmdShowMessages.Enabled = True

End Sub Sub cmdShowMessages_Click ()

'get/format/show messages from Submit Command API execution

Dim APIReturnCode As Integer 'return code

Dim Msg As String 'AS/400 message

Dim MsgID As String * 8 'AS/400 message ID

Dim MsgLength As Integer 'AS/400 message length

Dim ReturnMsg As String 'formatted return messages

Dim SeverityCode As Integer 'msg severity code

ReturnMsg = "" 'initialize

MsgLength = 100 'length of msg to retrieve

'loop through messages - end when no more messages in reply buffer

Do

Msg = Space$(MsgLength) 'initialize retrieved msg

APIReturnCode = EHNSR_GetMessage(hWnd, gblSystemName, SeverityCode,

MsgID, Msg, MsgLength, gblMsgBuffer, gblMsgBufferLength)

If APIReturnCode EHNSR_OK Then Exit Do 'no more msgs

'remove null terminator from Message ID (length 4 or 7)

If InStr(MsgID, Chr(0)) > 0 Then

MsgID = Mid$(MsgID, 1, InStr(MsgID, Chr(0)) - 1)

'extract message up to null terminator in message

If InStr(Msg, Chr(0)) > 0 Then

Msg = Mid$(Msg, 1, InStr(Msg, Chr(0)) - 1)

'Format MsgBox message for display

ReturnMsg = ReturnMsg & "Message ID: " & MsgID & Chr(10)

ReturnMsg = ReturnMsg & "Message: " & Msg & Chr(10) & Chr(10)

Loop

'display MsgBox with formatted messages

MsgBox ReturnMsg, MB_OK + MB_ICONINFORMATION,

"Messages from Submit Command API"

'disable Show Messages button - can only retrieve once from reply buffer
cmdShowMessages.Enabled = False
End Sub Sub txtCommand_Change ()

'disable Show Messages button - no longer valid for new message
cmdShowMessages.Enabled = False

End Sub Sub cmdExit_Click ()

Dim APIReturnCode As Integer 'return code

Figure 6: The cmdSubmit_Click Subroutine in RMTCMD.FRM

Figure 7: The cmdShowMessages_Click Subroutine in RMTCMD.FRM

Figure 8: The txtCommand_Change Subroutine in RMTCMD.FRM


'call Stop Conversation API to release any conversations

APIReturnCode = EHNSR_StopConversation(hWnd, gblSystemName)

End

End Sub

Figure 9: The cmdExit_Click Subroutine in RMTCMD.FRM


BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$