|
|
![]() |
|
|
Calling PC Commands from RPG by Kevin Vandever [The code for this article is available for download.] If you've kept up with my articles on the IBM Toolbox for Java, you've learned how to call iSeries programs, service programs, and stored procedures, as well as how to test iSeries data queue applications, from your PC, and using Java. This time I am going to show you how to run PC commands and applications from your RPG programs.
Final Piece of the Puzzle The good news is that you are closer than you think to being able to run PC commands from RPG. In fact, Shannon O'Donnell and I have already published most of the necessary information in previous articles. In this article, I will provide the final piece that lets you put the complete application together. So, first, let's talk about the application as a whole and then break it down into individual parts. The Big Picture This application will allow you to run a PC command from an RPG program using RPG, of course, a data queue, and Java. In my example, I envision a green-screen user wanting to pop up a browser on his PC when a function key is pressed inside his green-screen application (which is not so much a vision as a real-world request at my day job). There are probably many ways to accomplish this goal (and if anyone out there has a slicker method, please share it with me so I can be a hero at my day job!). One way is to write a macro, to run from your 5250 emulation client, that would scrape the screen to gather information and add that information to the URL. If there is no data you need from the screen, and you simply want to run a PC command, this might be the way to go, but in my application I need data from the iSeries, so therefore I want RPG to do some work before running the PC command. Another way to run PC commands from RPG would be to employ sockets instead of data queues. Sockets are very easy to use in Java, and you could write both the sockets server and the sockets client in Java and run the server on the iSeries. You could also write the sockets server in RPG (look for a future article on this subject), but it is a little more difficult. OK, enough of the alternatives. The way that I decided to accomplish this task was to use a keyed data queue to communicate between my RPG program and Java client on my PC. The reason I used keyed data queues is that I wanted one data queue on the iSeries to handle PC requests to all PCs attached to that iSeries. To do that, I key the data queue on the PC's IP address. That way, the RPG program can request to run a command on one person's PC and another person can request to run a command on his PC, and both requests will be handled by the same iSeries data queue and run on the appropriate PC. Get it? On each PC, a Java client will run in the background that listens for entries to the iSeries data queue. Since the data queue is keyed on the IP address, each PC will only retrieve messages slated for that particular PC. In my example, when the green-screen user presses the appropriate function key, an entry is written to the data queue containing the PC command to be run and the PC's IP address as the key. The Java program on the correct PC will retrieve the message from the data queue and pass it to the exec method contained in the Java runtime class, to be run. When the message is retrieved, it will automatically be removed from the queue, so no extra cleanup is required. Putting It All Together Now that you have an understanding of the overall project, let's gather the individual pieces. First, you will need to understand how to write requests to keyed data queues. I won't cover that in detail in this article, because there are two other articles you can access to gain a thorough understanding of data queues. They are "Data Queue Basics" and "Keyed Data Queues: The Key to Flexible Subfiles." When you write to your keyed data queue, you want to use your PC's IP address as the key. One way to access the IP address of your PC is to run IPCONFIG on your PC. However, if you do that, you will be hard-coding the IP address inside your RPG program and that is just wrong on so many levels. There is another way: You can call an API to get the client's IP address. (Try downloading the code in the article "Determining a PC's IP Address," and see if it works for you.) Now that you have all the RPG and data queue tools on the iSeries side that are necessary to complete this application, let's take a look at the Java client that will exist on the PC to see what it's going to do. I've included a Java application, CommandServerJDQ.java, that will handle everything for you. It will listen on the appropriate keyed data queue, and when it retrieves a message, keyed by the IP address, it will pass that message to the exec method and run that command. Let's dig into the code more closely, shall we? The first interesting thing you might note about the code resides in the compile instructions at the top. Notice the -deprecation option used in the javac command. This is here because of use of the AS400Text class, which is used to convert text from Unicode to EBCDIC. A new implementation of this class has been introduced that accepts an additional parameter. This parameter is the AS400 connection object. I continue to use the deprecated version of this class because it seems to work, but feel free to check out the AS/400 Toolbox documentation for the AS400Text class, and add the new parameter; otherwise, compile this source using the -deprecation option. This Java application creates a nice window from which to run. This is not necessary for the application to work, so I'm not going to go into detail about it. The first thing I want to look at is the Try/Catch block that retrieves the IP address and converts it to EBCDIC. This is used to obtain the key that accesses the appropriate data queue messages. This logic retrieves the local host Internet address and, using the getHostAddress method, gets the IP address for the specific client and places the results into a String variable. That string is then converted to EBCDIC, using the deprecated AS400Text class. The next block of code is used to connect to the AS/400 and create a data queue. To use the AS/400 and data queue classes, download and install the Toolbox for Java from IBM's Web site and add the appropriate JAR files to your CLASSPATH. Please refer to "Calling A Program Using the iSeries Toolbox For Java" for detailed information on the Toolbox, including installation instructions. OK, back to the code. The host = new AS400() line attempts to connect to an AS/400. Since there is nothing placed inside the parentheses, you will be prompted for the system name or IP, user ID, and password. You can include this information as parameters to the AS400() object, thus saving you from typing them in every time you run the program, or you can leave them blank, as I have done, and key them in every time you run the application. (Again, refer to "Calling A Program Using the iSeries Toolbox For Java" for more information.) Once you are connected to the AS/400, you will then attempt to create a keyed data queue, using the create method, from the KeyedDataQueue class. The only two parameters you need are the key length, 20, and the maximum length of the data queue message, 500. The rest of the information was included when the KeyedDataQueue object was instantiated. If the data queue already exists, a message will pop up inside your window telling you so; otherwise, a keyed data queue will be created on the AS/400. The next block of code listens on the keyed data queue, using the KeyedDataQueue read method. The three parameters used in this method are the key, which is the IP address of the PC, the wait time, which is indefinite and signified by a negative number, and how the key is to be processed, in this case *EQ, or equal. All of this means that this method will wait on this line of code, attempting to access the data queue, until an entry exists with a matching key. A zero (0) in the wait time would have caused the read method to read the queue and to continue processing immediately, regardless of whether a matching entry for the key was found. A positive number would have told the read option to wait that number of seconds before continuing to the next line. The *EQ parameter tells the read method to look for entries with keys equal to the key data in the first parameter. You could also read entries less than (*LT), less than or equal to (*LE), greater than (*GT), or greater than or equal to (*GE), the key field. Once you've successfully read a message from the queue, you use the getData method to place the message into a byte array. Then you convert that byte array from EBCDID to a String variable, using the textConverter method from the AS400Text class. Once the data is converted, it's time to run the command contained in the message. To do that, you run the runCommand method, which is included in the sample Java application and contains the call to the exec method from the Runtime class. Around those simple calls is a lot of error checking to catch a host of potential AS/400 and PC errors. However, knowing the audience I'm dealing with here, this is nothing more than window dressing, as our stuff always works perfectly the first time. PC and AS/400 As One You now have a complete application, should you need to run PC commands from your RPG programs. Remember to include the complete path name when writing the PC command to the data queue. It isn't always necessary. For example, to run NOTEPAD.EXE, all you need to do is to send a message containing "NOTEPAD.EXE," but if want to run other commands, such as internet explorer, you'll need the appropriate qualified path name. Enjoy!
|
Editors
Contact the Editors |
|
Last Updated: 9/12/02 Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |