Click here to Skip to main content
15,867,929 members
Articles / Programming Languages / C#

Using EHLLAPI in C#

Rate me:
Please Sign up or sign in to vote.
4.68/5 (16 votes)
17 Feb 2005CPOL3 min read 193.7K   9.3K   35   69
This article will explain how to interact with AS/400 applications using the PCSHLL32.DLL library distributed with IBM Client Access emulator.

Image 1

Using EHLLAPI from C#

EHLLAPI (Extended High Level Language Application Programming Interface) is a standard library to build interfaces to AS400 applications. It's distributed with all major emulation vendors (RUMBA, IBM Client Access, ...), and it's installed automatically as DLL.

This article will explain how to interact with AS/400 applications using the library distributed with IBM Client Access emulator: PCSHLL32.DLL. If you use a different emulation software, you can apply the concepts exposed in this article with some minor modifications.

EHLLAPI Concept

In a lot of companies, data integration is not so simple because a lot of programs are very old and databases are not well structured. Even if data can be accessed using ODBC drivers, the real problem is the knowledge of data structures and integration: which tables I must change to insert a new product code? Where are all the data of a customer (in which tables)? These and a lot of other questions have a simple answer: ask to users and learn the commands they type on the screen to insert or read information. You translate the problem: it's not important to know the logic to manipulate data, what's important is to know the "video" command the users type.

The interface used to interact with AS/400 is called "screen scraping": it's based on the fact that emulator software use a char interface to interact with AS/400 programs. Using this interface, you can read from and write to emulation screens. This really simple mechanism reveals all its power if inserted in a high level window program.

DLL Exported Function

PCSHLL32.DLL includes just a function named HLLAPI that receives a parameter (function code): by changing the value of this parameter, we can perform all the operations. There are almost one hundred functions available in the DLL and declared as const inside code. In my experience, I used just five of these functions:

  • HA_CONNECT_PS: connect to a client session (every session is identified by an ID: "A", "B", and so on).
  • HA_DISCONNECT_PS: disconnect from a client session.
  • HA_SET_CURSOR: set the cursor in the absolute position (rows * 80 (or 132) + cols).
  • HA_SENDKEY: send a string to a client session.
  • HA_COPY_PS_TO_STR: read from video.
  • HA_WAIT: wait for session deblocking.

To import the DLL function, I used this code:

public class EhllapiFunc
{
    [DllImport("PCSHLL32.dll")]
    public static extern UInt32 hllapi(out UInt32 Func, 
      StringBuilder Data, out UInt32 Length, out UInt32 RetC);
}

This class contains just a static function referrer to the PCSHLL32 function. This function return 0 if all is OK, otherwise it returns an error code (see inside the code). Parameters are declared without statement because they are used in two directions (to send and receive value). Depending on the Func parameter, Data, Length and RetC parameters have different meanings.

Inside Class Code

I created a class named EhllapiWrapper. This class exposes five static methods. The structure of these methods is very simple: initialize parameter, call HLLAPI function exposed by the EhllapiFunc class, and return value:

public static UInt32 Connect(string sessionID) 
{ 
 StringBuilder Data = new StringBuilder(4);
 //Data will contain the ID code of Session

 Data.Append(sessionID);
 UInt32 rc=0;
 UInt32 f=HA_CONNECT_PS; //function code
 UInt32 l=4; //lenght of data parameter
 return  EhllapiFunc.hllapi(out f, Data, out l, out rc);
 //return error code
}
public static UInt32 Disconnect(string sessionID) 
{
 StringBuilder Data = new StringBuilder(4); 
 Data.Append(sessionID);
 UInt32 rc=0;
 UInt32 f=HA_DISCONNECT_PS;
 UInt32 l=4;
return  EhllapiFunc.hllapi(out f, Data, out l, out rc);
}
public static UInt32 SetCursorPos(int p)
{
 StringBuilder Data = new StringBuilder(0);
 //no Data parameter is required

 UInt32 rc=(UInt32) p;
 //rc parameter contains the curson position

 UInt32 f=HA_SET_CURSOR;
 UInt32 l=0;
 return EhllapiFunc.hllapi(out f, Data, out l, out rc);
}
public static UInt32 GetCursorPos(out int p)
{
 StringBuilder Data = new StringBuilder(0);
 UInt32 rc=0;
 UInt32 f=HA_QUERY_CURSOR_LOC;
 UInt32 l=0; //return position
 UInt32 r = EhllapiFunc.hllapi(out f, Data, out l, out rc);
 p = (int)l;
 return r;
}
public static UInt32 SendStr(string cmd)
{
 StringBuilder Data = new StringBuilder(cmd.Length);
 //Data has the length of cmd string

 Data.Append(cmd);
 UInt32 rc=0;
 UInt32 f=HA_SENDKEY;
 UInt32 l=(UInt32)cmd.Length;
 //l parameter contain the length of cmd string

 return  EhllapiFunc.hllapi(out f, Data, out l, out rc);
}

public static UInt32 ReadScreen(int position, int len, out string txt)
{
 StringBuilder Data = new StringBuilder(3000);
 //Initialization to a MAX char 
 //(> maximum number of char in a screen session)

 UInt32 rc=(UInt32)position;
 //set initial position to start reading from

 UInt32 f=HA_COPY_PS_TO_STR;
 UInt32 l=(UInt32)len;
 //set the number of chars that 
 //function will read from position

 UInt32 r = EhllapiFunc.hllapi(out f, Data, out l, out rc);
 txt=Data.ToString(); //result
 return r;
}
public static UInt32 Wait()
//just wait for execution of a command on session
{
 StringBuilder Data = new StringBuilder(0);
 UInt32 rc=0;
 UInt32 f=HA_WAIT ;
 UInt32 l=0;
 UInt32 r = EhllapiFunc.hllapi(out f, Data, out l, out rc);
 return r;
}

Using EhllapiWrapper Class

A typical use of the wrapper class is this one:

  1. Connect to session.
  2. Set cursor position.
  3. Send string.
  4. Read screen.
  5. Disconnect.

Some Notes

Session ID for Client Access emulator is a char where "A" identifies the first session opened, "B" the second one, and so on. You can send a special key to the session using a particular syntax (see the comment section inside Wrapper class code). For example, ENTER corresponds to @E, F1 key to @1, and so on.

Demo Code

Demo code includes a simple form containing five buttons (one for every method). I used a different color to identify functions and parameters. Form has TopMost = true, so it remains visible when you interact with session. So start a Client Access session, specify ID (typically "A" if it's the first session started), and push Connect. A message box is displayed with return code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Italy Italy
I'm a Delphi programmer since the 1.0 version.
My acual interest concern all modern language and development tools.
I'm a runner (3H:12M) to Pisa Marathon in 2002.

Comments and Discussions

 
AnswerRe: Ibm 3270 interface issues Pin
Member 989925610-Mar-13 13:51
Member 989925610-Mar-13 13:51 
GeneralThis was easily adapted to Rumba Web to Host Pin
X3n0Byt37-Jun-10 15:17
professionalX3n0Byt37-Jun-10 15:17 
GeneralRe: This was easily adapted to Rumba Web to Host Pin
Member 439774812-Apr-11 9:05
Member 439774812-Apr-11 9:05 
GeneralRe: This was easily adapted to Rumba Web to Host Pin
X3n0Byt312-Apr-11 9:11
professionalX3n0Byt312-Apr-11 9:11 
GeneralRe: This was easily adapted to Rumba Web to Host Pin
Member 439774812-Apr-11 9:13
Member 439774812-Apr-11 9:13 
GeneralSaved my Live Pin
UR-IT12-Oct-09 7:43
UR-IT12-Oct-09 7:43 
QuestionDo you have delphi wrapper of this? Pin
Member 331807831-Aug-09 5:28
Member 331807831-Aug-09 5:28 
GeneralSeagull Emulator Pin
caherdavinbhoy4-Mar-09 5:24
caherdavinbhoy4-Mar-09 5:24 
Has anyone worked with the Seagull Emulator for AS400 - Silverlake Browser Interface? I am working with the Seagull dll - SEHLLAPI.dll which has an exported method "HLLAPI" similar to the PCSHLL32.dll exported method "hllapi".

My problem is that I can't seem to connect to the AS400 session using any Session ID from A thru Z using the SEHLLAPI.dll and Seagull Emulator. I launch the emulator and loop on the "Query Session Status" method, but the return code is always 1. I have worked with the Client Access PCSHLL32.dll and Passport's PassHll.dll Emulators and had no problem connecting to the AS400 session.

Any ideas would be greatly appreciated.
General3270 vs 5250 Problem Pin
Deadmeat25-Jul-07 7:32
Deadmeat25-Jul-07 7:32 
GeneralVBA EHLLAPI Question Pin
foundryqa9-Jul-07 13:07
foundryqa9-Jul-07 13:07 
GeneralRe: VBA EHLLAPI Question Pin
bertonciniluca10-Jul-07 22:38
bertonciniluca10-Jul-07 22:38 
GeneralRe: VBA EHLLAPI Question Pin
foundryqa29-Jul-07 11:57
foundryqa29-Jul-07 11:57 
QuestionDebug v Release Issue Pin
Grandizer Coen22-Mar-07 13:04
Grandizer Coen22-Mar-07 13:04 
AnswerRe: Debug v Release Issue Pin
bertonciniluca22-Mar-07 21:45
bertonciniluca22-Mar-07 21:45 
QuestionRe: Debug v Release Issue Pin
Grandizer Coen23-Mar-07 2:29
Grandizer Coen23-Mar-07 2:29 
QuestionIs there new way to handle mainframe in C#? Pin
li_robert15-Mar-07 8:40
li_robert15-Mar-07 8:40 
AnswerRe: Is there new way to handle mainframe in C#? Pin
Luca Bertoncini15-Mar-07 9:07
Luca Bertoncini15-Mar-07 9:07 
GeneralRemote control Pin
RogerFoxDogs26-Jan-07 13:45
RogerFoxDogs26-Jan-07 13:45 
AnswerRe: Remote control Pin
Luca Bertoncini26-Jan-07 20:43
Luca Bertoncini26-Jan-07 20:43 
GeneralDllNotFoundException Pin
Swenni19-Jun-06 6:06
Swenni19-Jun-06 6:06 
GeneralRe: DllNotFoundException Pin
Luca Bertoncini29-Jul-06 7:33
Luca Bertoncini29-Jul-06 7:33 
GeneralRe: DllNotFoundException Pin
gavin.morris16-Mar-07 0:46
gavin.morris16-Mar-07 0:46 
GeneralRe: DllNotFoundException Pin
bertonciniluca16-Mar-07 2:50
bertonciniluca16-Mar-07 2:50 
GeneralRe: DllNotFoundException Pin
gavin.morris16-Mar-07 4:34
gavin.morris16-Mar-07 4:34 
AnswerRe: DllNotFoundException Pin
bertonciniluca16-Mar-07 4:45
bertonciniluca16-Mar-07 4:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.