Theme:
v
APL+Win 13.2 ⎕CSE Tutorial (2)

This page contains more examples showing how to use the new APL+Win Interface to .Net 4.5 using the new ⎕CSE System Function

It contains 2 examples:

  • a C# script entirely embedded into an APL function
  • the same C# script embedded in a C# DLL

In both cases, we use the new ⎕CSE System Function to run the scripts from APL.

Example 7: Using .Net to programmatically send an Email

In this example we will create a more complex script, though still very simple. Since the script contains more lines, we will store it in an APL function.

Here is the function:

    ∇ SendEmail;s;z
[1]   s←''
[2]   s←s,⊂'using System;'
[3]   s←s,⊂'using System.Net;'
[4]   s←s,⊂'using System.Net.Mail;'
[5]   s←s,⊂'public class Emails'
[6]   s←s,⊂'{'
[7]   s←s,⊂'    public string UserName { get; set; }'
[8]   s←s,⊂'    public string Password { get; set; }'
[9]   s←s,⊂'    public string Host { get; set; }'
[10]  s←s,⊂'    public int Port { get; set; }'
[11]  s←s,⊂'    public string From { get; set; }'
[12]  s←s,⊂'    public string To { get; set; }'
[13]  s←s,⊂'    public string Subject { get; set; }'
[14]  s←s,⊂'    public string Body { get; set; }'
[15]  s←s,⊂''
[16]  s←s,⊂'    public void SendEmail()'
[17]  s←s,⊂'    {'
[18]  s←s,⊂'        using (MailMessage email = new MailMessage())'
[19]  s←s,⊂'        {'
[20]  s←s,⊂'            email.From = new MailAddress(From);'
[21]  s←s,⊂'            email.To.Add(To);'
[22]  s←s,⊂'            email.Subject = Subject;'
[23]  s←s,⊂'            email.Body = Body;'
[24]  s←s,⊂'            SmtpClient client = new SmtpClient(Host, Port);'
[25]  s←s,⊂'            client.Credentials = new NetworkCredential(UserName, Password);'
[26]  s←s,⊂'            client.Send(email);'
[27]  s←s,⊂'        }'
[28]  s←s,⊂'    }'
[29]  s←s,⊂'}'
[30]  s←⊃s
[31]
[32]  ⍝ Initialize the CSE object
[33]  ⎕cself←'c'⎕cse'Init' 'System' 'System.Net'
[34]
[35]  ⍝ Compile the script
[36]  z←⎕cse'Exec's
[37]  :if z=¯1 ⋄ ⎕error⎕cse'GetLastError' ⋄ :endif
[38]
[39]  ⍝ Run the script
[40]  s←''
[41]  s←s,⊂'Emails mail = new Emails();'
[42]  s←s,⊂'mail.UserName = "xxxxxx";'
[43]  s←s,⊂'mail.Password = "xxxxxx";'
[44]  s←s,⊂'mail.Host = "smtp.orange.fr";'
[45]  s←s,⊂'mail.Port = 25;'
[46]  s←s,⊂'mail.From = "eric@lescasse.com";'
[47]  s←s,⊂'mail.To = "eric@lescasse.com";'
[48]  s←s,⊂'mail.Subject = "Test Message";'
[49]  s←s,⊂'mail.Body = "This is a test message.";'
[50]  s←s,⊂'mail.SendEmail();'
[51]  s←⊃s
[52]
[53]  z←⎕cse'Exec's
[54]  :if z=¯1 ⋄ ⎕error⎕cse'GetLastError' ⋄ :endif
[55]
    ∇

Here are some comments:

  • I have replaced my own SMTP Credentials (UserName and Password by "xxxxxx" on lines 42 and 43. If you want to use this APL function, be sure to replace "xxxxxx" by your own credentials. Also change the Host property to use your own SMTP host on line 44
  • lines 1 to 30 define a first C# script: this script defines a C# class called Emails. The Emails class include 8 properties (UserName, Password, Host, Port, From, To, Subject and Body) and 1 method (SendEmail)
  • line 33 creates an instance of the CSE object: note that we declare that we will be using the .Net Framework System.Net DLL. This is required because the MailMessage, MailAddress, SmtpClient and NetworkCredential classes we need to use to send an Email using .Net are defined in System.Net DLL namespaces.
    How do you know that if you are a C# novice user?
    Answer: Google (or C# books: there are hundreds of them).
  • Note that this script declares on line 3 and 4 that we will be using the System.Net and the System.Net.Mail namespaces. This is not required, but if we did not include those lines, we would have to wirte line 18 as follows:
    using (System.Net.Mail.MailMessage email = new System.Net.Mail.MailMessage())
    instead of just:
    using (MailMessage email = new MailMessage())
  • On line 36 we run the first script: the effect of running this script is to define the Emails class in .Net memory so that we can later use it.
  • on lines 40 to 51 we define a second C# script: the role of this script is to use the Emails class to programmatically send an Email. All we have to do is to set each of the 8 Emails properties appropriately and then to call the SendEmail method.
  • finally, on line 53 we run this second script which results in sending me an Email

Let's now use the SendEmail function (of course, after I have defined the correct UserName and Password on lines 42 and 43):

      SendEmail

A few seconds later, I do receive the Email in my Outlook Email client application:

Email received in Outlook

If you have a valid APL+Win v13.2 Subscription, I leave it to you as an exercise to update the SendEmail APL function to support:

  • file attachments
  • html body
  • CC list
  • BCC list
  • delivery notification options
  • reply to address
  • body encoding
  • etc.

You should find example of all that on Google. The beauty of the .Net Framework and C# is that it generally lets you do complex things extremely easily.

Example 8: Using .Net to programmatically send an Email using a DLL

You need not create your C# script in APL+Win and embed it in an APL function.

In fact, this is definitely not how I recommend to do things.

You're much better off defining your script directly in Microsoft Visual Studio 2012 or Microsoft Visual Studio 2012 Express (free)

Here is how to proceed:

  1. start Microsoft Visual Studio 2012
  2. choose: File / New Project...
  3. be sure that .NET Framework 4.5 is selected in the top combo box
  4. select: Class Library
  5. enter a Name of: Tools
  6. click OK
  7. in Solution Explorer, right click Class1.cs and rename it to: Emails.cs

    The C# Emails.cs class gets displayed and should read:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Tools
    {
        public class Emails
        {
        }
    }
    

    Change it so that it reads like your APL script. It should exactly read:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Mail;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Tools
    {
        public class Emails
        {
    		public string UserName { get; set; }
    		public string Password { get; set; }
    		public string Host { get; set; }
    		public int Port { get; set; }
    		public string From { get; set; }
    		public string To { get; set; }
    		public string Subject { get; set; }
    		public string Body { get; set; }
    
    		public void SendEmail()
    		{
    			using (MailMessage email = new MailMessage())
    			{
    				email.From = new MailAddress(From);
    				email.To.Add(To);
    				email.Subject = Subject;
    				email.Body = Body;
    				SmtpClient client = new SmtpClient(Host, Port);
    				client.Credentials = new NetworkCredential(UserName, Password);
    				client.Send(email);
    			}
    		}
    	}
    }
    

    As you can see this is basically the same script as the first one included in our SendEmail APL function.

  8. Right click the Tools project in Solution Explorer and select Build
    You should see: Build succeeded displayed in the status bar
    Also, if the compilation succeeded, a DLL named Tools.dll has been created in the Bin\Debug folder of your C# Solution

Now that we have a DLL, we can use it from APL with the ⎕CSE system function.

Let's create an APL function called SendEmailFromDLL for that:

    ∇ SendEmailFromDLL;s;z;⎕cself
[1]
[2]   ⎕cself←'c'⎕cse'Init' 'System'
[3]   z←⎕cse'LoadAssembly' 'D:\Documents\Visual Studio 2012\Projects\Test\Tools\Tools\bin\Debug\Tools.dll'
[4]
[5]   s←''
[6]   s←s,⊂'using Tools;'
[7]   s←s,⊂'Emails mail = new Emails();'
[8]   s←s,⊂'mail.UserName = "xxxxxx";'
[9]   s←s,⊂'mail.Password = "xxxxxx";'
[10]  s←s,⊂'mail.Host = "smtp.orange.fr";'
[11]  s←s,⊂'mail.Port = 25;'
[12]  s←s,⊂'mail.From = "eric@lescasse.com";'
[13]  s←s,⊂'mail.To = "eric@lescasse.com";'
[14]  s←s,⊂'mail.Subject = "Test Message";'
[15]  s←s,⊂'mail.Body = "This is a test message.";'
[16]  s←s,⊂'mail.SendEmail();'
[17]  s←⊃s
[18]
[19]  z←⎕cse'Exec's
[20]  :if z=¯1 ⋄ ⎕error⎕cse'GetLastError' ⋄ :endif
[21]
    ∇

Here are some comments:

  • line 2 creates an instance of the CSE object
    We need only declare the minimum which is the System DLL, since needed declarations are included in the .Net DLL itself
  • the key line here is line 3 which loads the Tools.dll into CSE memory so that we can use it from APL
  • line 6 is required to avoid having to write line 7 as follows:
    Tools.Emails mail = new Tools.Emails();
  • lines 7 to 20 are identical to the end of the SendEmail function

The moral of examples 8 and 9 is that it is better and easier to use Microsoft Visual Studio to create a DLL than to write you script directly in APL.

If you use Visual Studio, you benefit from:

  1. syntax coloring
  2. Intellisense
  3. powerful debugging facilities
  4. fantastic script editor
  5. etc.

all things you don't have at hand if you write your script directly in APL. The most important thing in my opinion is that it's going to be much easier to debug a script in Visual Studio than to do it if you write it directly in APL.

Moreover, you'll be able to reuse your DLL script more easily as it will stay external to your APL workspaces.

Finally, a single C# DLL can contain multiple classes, even a very large number of classes, so you can regroup all your .Net utilities into a single DLL. In that case Visual Studio and its Solution Explorer makes it inifinitly simpler to manage all these classes.

 

CSE Tutorial (1)...
CSE Tutorial (3)...
CSE Tutorial (4)...
CSE Tutorial (5)...