Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5643
  • Last Modified:

.Net (cwbx) calling cl program on as400

I have an excel add-in I created in Visual studio for office that calls a CL program on our as400. The .Net side of things works fine. The problem is the if the CL program has a problem and errors my excel Add-in does not know about it because the as400 is in MSGW mode waiting for some one to enter C D I R so it can continue dumping itself. My .Net app just sits there waiting for the command on the as400 to finish running.

I am trying to figure out what I need to do to manage the as400 errors the user of the excel add-in knows something bad happened.

I am thinking that the CL program need to be rewritten or maybe converted to an RPG program that will return something to my program that lets it know if all went well or not.

Or is there a way to just runt the CL program in a way that it will not do the the MSGW thing and just go ahead and dump some errors that my app will get it in cwbx.Command.Errors.

I just need to know what needs to happen on the as400 to get around this so I can tell our as400 programmer what to do. He has never dealt with anything like this before so nether of use are sure what to do for the best solution.

cwbx.AS400System as400 = new cwbx.AS400SystemClass();
            cwbx.ProgramParameters parameters = new ProgramParametersClass();
            cwbx.Program program = new cwbx.Program();
            cwbx.Command cmd = new Command();
            
            Debug.Print("before try");
            try
            {
                
               as400.Define("XX.XX.XX.XX");
                as400.UserID = "USERID";
                as400.Password = "PASSWORD";
                as400.PromptMode = cwbcoPromptModeEnum.cwbcoPromptNever;
                as400.Signon();
                cmd.system = as400;
                
                //this did not work
                //cmd.Run("SBMJOB CMD(CALL PGM(MIKE/TESTER) PARM('645')) JOB(EXTEST) USER(EXCELUSR) INQMSGRPY(*DFT) HOLD(*NO)");                                                   
 
                cmd.Run("CALL PGM(MIKE/TESTER) PARM('645')");
                
                Debug.Print("after call");
            }
            catch (Exception ex)
            {
                Debug.Print("Exception = "+ ex.Message + " trace " + ex.StackTrace);
                if (cmd.Errors.Count > 0)
                {
                    foreach (cwbx.Error error in cmd.Errors)
                    {
                        System.Diagnostics.Debug.Print("CMD Errors : " + error.Text);
                    }
 
                }
                if (as400.Errors.Count > 0)
                {
                    foreach (cwbx.Error error in as400.Errors)
                    {
                        System.Diagnostics.Debug.Print("AS400 Errors : " + error.Text);
                    }
                }
 
                if (program.Errors.Count > 0)
                {
                    foreach (cwbx.Error error in program.Errors)
                    {
                        System.Diagnostics.Debug.Print("Program Errors : " + error.Text);
                    }
                }
            }
            finally
            {
               // as400.Disconnect(cwbcoServiceEnum.cwbcoServiceAll);
            }
        }

Open in new window

0
mhopkins9901
Asked:
mhopkins9901
  • 3
2 Solutions
 
rwardCommented:
You can use the MONMSG command in the CL program to specifically monitor for the errors your CL is getting which you can then deal with the error gracefully.  You can also monitor for error messages globally by having the MONMSG command as the first command in the CL program after PGM and declares.

A good simple explanation of how to use error handling in CL can be found at
http://www.400school.com/artmsg.htm   
0
 
Gary PattersonVP Technology / Senior Consultant Commented:
Assuming it is an OPM CL program (CLP, not CLLE), I'd recommend the programmer use the Gossip method from this article, and in ERROR3: I'd also add a DMPCLPGM and a DSPJOBLOG OUTPUT(*PRINT) right before the final ESCAPE message is sent to terminate the C.  

Using this technique means that the job NEVER gets stuck in a MSGW, and if you use it with my two modifications it also forces the program to produce a job log and dump of all CL program variables (even if joblog generation is otherwise disabled for the job).  It will bubble the lower-level diagnostic and escape messages related to program failure back up to the calling service where they will be made visible through your cwbx.Command.Errors collection.

Well-behaved AS/400 programs (regardless of language), handle errors in exactly the same fashion:  If the current module is interactive and the user can fix the problem, show them a message in an interactive display and let them deal with it.  Otherwise (non-interactive program, or not handlable by the user), receive and resend the relevant diagnostic and escape messages back to the current program's calling program.  Sending an *ESCAPE message will terminate teh current program.  Programs higher in teh call stack should follow the same basic rules: hnald it if you can, if not, repeat messages up one level and escape:

http://www.400school.com/artmsg.htm

If the called program is a CLLE, especially a mulitple-module CLLE, it may require a different approach.  Post back if that is the case.

You can check the CL program's type attribute using the green-screen WRKPGM command.

- Gary Patterson


0
 
Gary PattersonVP Technology / Senior Consultant Commented:
Assuming it is an OPM CL program (CLP, not CLLE), I'd recommend the programmer use the Gossip method from this article, and in ERROR3: I'd also add a DMPCLPGM and a DSPJOBLOG OUTPUT(*PRINT) right before the final ESCAPE message is sent to terminate the C.  

Using this technique means that the job NEVER gets stuck in a MSGW, and if you use it with my two modifications it also forces the program to produce a job log and dump of all CL program variables (even if joblog generation is otherwise disabled for the job).  It will bubble the lower-level diagnostic and escape messages related to program failure back up to the calling service where they will be made visible through your cwbx.Command.Errors collection.

Well-behaved AS/400 programs (regardless of language), handle errors in exactly the same fashion:  If the current module is interactive and the user can fix the problem, show them a message in an interactive display and let them deal with it.  Otherwise (non-interactive program, or not handlable by the user), receive and resend the relevant diagnostic and escape messages back to the current program's calling program.  Sending an *ESCAPE message will terminate teh current program.  Programs higher in teh call stack should follow the same basic rules: hnald it if you can, if not, repeat messages up one level and escape:

http://www.400school.com/artmsg.htm

If the called program is a CLLE, especially a mulitple-module CLLE, it may require a different approach.  Post back if that is the case.

You can check the CL program's type attribute using the green-screen WRKPGM command.

- Gary Patterson


0
 
Gary PattersonVP Technology / Senior Consultant Commented:
Sorry about the double post!  No idea how I did that!
0
 
mhopkins9901Author Commented:
Thanks for the help rward and Gary you were both helpful and got me track. If EE would let me I would have given you both 500 points and not had to split it between you. Thanks again
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now