Pages

Thursday, February 14, 2002

Peoplecode FTP function

Many processes are executed on the server for performance reasons. Their output and log files, such as process logs and *.spf files from SQR, are usually handled in the following ways:


  • loaded into a table to be viewed in a on-line panel

  • saved to another location and picked up through 3-party reporting tools

  • moved to another server by using a server script

  • Here's a simple alternative to the above methods - FTP to client directly and use the rich set of tools on the client side to view or manipulate it.
    The function accepts 5 parameters:

  • FTP site

  • Directory

  • File Name

  • Login ID

  • Password

  • The sample code retrieves a readme.txt from Microsoft's ftp site into the directory path pointed to by the environment variable TEMP. As is, it supports the Get operation in ASCII mode. Binary mode and other operations can be easily implemented. It’s doable to even build a simple FTP client into PS.


  • Copy the function declaration:

  • Declare Function InternetOpenA Library "wininet.dll" (string Value As string, long Value As number,
    string Value As string, string Value As string, long Value As number) Returns long As number;
    Declare Function InternetConnectA Library "wininet.dll" (long Value As number, string Value As
    string, integer Value As number, string Value As string, string Value As string, long Value As
    number, long Value As number, long Value As number) Returns long As number;
    Declare Function FtpSetCurrentDirectoryA Library "wininet.dll" (long Value As number, string Value
    As string) Returns long As number;
    Declare Function FtpGetFileA Library "wininet.dll" (long Value As number, string Value As string,
    string Value As string, long Value As number, long Value As number, long Value As number, long Value
    As number) Returns boolean;
    Declare Function InternetCloseHandle Library "wininet.dll" (long Value As number) Returns integer
    As number;Function FTPGet(&HOST As string, &DIR As string, &FILE As string, &ACCT As string, &PW As string)
    Returns boolean;
    &OPEN_PRECONFIG = 0;
    &FTP_PORT = 21;
    &INET_FTP = 1;
    &INET_PASSIVE = 134217728;
    &FTP_ASCII = 1;
    &HOPEN = InternetOpenA("Peoplecode FTP", &OPEN_PRECONFIG, "", "", 0);
    If &HOPEN > 0 Then
      &HCONN = InternetConnectA(&HOPEN, &HOST, &FTP_PORT, &ACCT, &PW, &INET_FTP,
      &INET_PASSIVE, 0);
      If &HCONN > 0 Then
         If All(&DIR) Then
            &HDIR = FtpSetCurrentDirectoryA(&HCONN, &DIR);
         Else
            &HDIR = 1;
         End-If;
         If &HDIR Then
            &HFILE = FtpGetFileA(&HCONN, &FILE, GetEnv("TEMP") | "\" | &FILE, 0, 0, &FTP_ASCII, 0);
            If &HFILE Then
               &RC = InternetCloseHandle(&HCONN);
               &RC = InternetCloseHandle(&HOPEN);
               Return True;
            End-If;
         End-If;
         &RC = InternetCloseHandle(&HCONN);
      End-If;
      &RC = InternetCloseHandle(&HOPEN);
    End-If;
    Return False;
    End-Function;


  • Copy the sample test to a FieldChange event run on the Client:

  • &XX = FTPGet("ftp.microsoft.com", "softlib", "readme.txt","anonymous","");
    If &XX Then
    WinExec("start " | GetEnv("TEMP") | "\"|"readme.txt", 1, False);
    Else
    WinMessage("fail");
    End-If;
    For NT client, replace "start" with "cmd /c start" so the line looks like:
    WinExec("cmd /c start " | GetEnv("TEMP") | "\"|"readme.txt", 1, False);
    Account ID & Password considerations - The demonstration uses a simple "anonymous" and null as password. Additional code can be added to prompt the user. They can also be defined based on operator ID/Classes. Permission for this account should then be set up accordingly for the FTP purpose only. The retrieval of ID & password can be encapsulated in the FTP function as well. The function then requires 3 parameters instead of 5.

    (This article was originally published on 02/14/02 at www.slerp.com. PSTools version 5,6,7)


    Thursday, February 7, 2002

    Peoplecode 3-tier Detection

    The Status Bar is a control that is at the bottom of a panel that displays information about the application status. It is divided into individual panes. Each pane displays specific aspects of the process/function the user is in. 5 panes are present in v.7 and 6 panes in v.8. This article will demonstrate a platform independent method to detect 3-tier connection by accessing the information stored on status bar, provided the database sever and application server have different names.
    Take a look at a sample status bar:

    The 1st pane does not have a border, and is used for panel loading. We are interested in the 3rd pane. It displays the server name, GF75DMO. In PS8, there’s another pane for Time, but server name is still on 3rd pane.
    If server name is not displayed, turn it on in Configuration Manager Display tab:




  • Copy the function declaration:

  • Declare Function GetActiveWindow Library "user32"
    () Returns long As number;
    Declare Function GetWindow Library "user32"
    (long Value As number, long Value As number) Returns long As number;
    Declare Function GetClassNameA Library "user32"
    (long Value As number, string Ref As string, integer Value As number) Returns long As number;
    Declare Function SendMsg2 Library "user32" Alias "SendMessageA"
    (long Value As number, integer Value As number, integer Value As number, string Ref As string)
    Returns long As number;Function GetSB(&PANETEXT As string) Returns boolean;
    &STATBAR = "msctls_statusbar32";
    &HWND = GetActiveWindow();
    &GW_CHILD = 5;
    &GW_HWNDNEXT = 2;
    
    &MAXLEN = 128;   &CLSNAME = Rept(" ", &MAXLEN);
    &CWND = GetWindow(&HWND, &GW_CHILD);
    While &CWND > 0
    &CLSLEN = GetClassNameA(&CWND, &CLSNAME, &MAXLEN);
    If &CLSNAME = &STATBAR Then
      Break;
    End-If;
    &CWND = GetWindow(&CWND, &GW_HWNDNEXT);
    End-While;
    If &CWND > 0 Then
    &NPARTS = 0;
    &CORD = 0;
    &SB_GETTEXTA = 1026;
    &RC = SendMsg2(&CWND, &SB_GETTEXTA, 2, &PANETEXT);
    If &RC > 0 Then
      Return True;
    End-If;
    End-If;
    Return False;
    End-Function;



  • Test the function in a FieldChange event:

  • &XX = GetSB(&PANETEXT);
    If &XX Then
    If &PANETEXT = "MyAppSvr" Then
    WinMessage("3-tier");
    Else
    WinMessage("2-tier");
    End-If;
    Else
    WinMessage("fail");
    End-If;
    The server name is returned in &PANETEXT. Compare it to a list of known App Server names. If a match is found, then the user has logged into the App server.
    As with all external Windows function APIs, if your app server is not NT, set the execution location of this code to client:

    You can also read or write into this or other panes on the status bar. But there are some considerations when writing text to it. Please email the author if you’d like to see how to do it.

    (This article was originally published on 02/07/02 at www.slerp.com. PSTools version 5,6,7)