568 - PugChallenge2016x
Download
Report
Transcript 568 - PugChallenge2016x
Pug Challenge Americas 2016 – Manchester
Progress .NET, Not Progress GUI for .NET
Presented by: Tom Bergman
[email protected]
.Net Framework – What is it?
http://msdn.microsoft.com/en-us/library/gg145045(v=vs.110).aspx
The .NET Framework class library is a library of classes, interfaces, and
value types that provide access to system functionality. It is the
foundation on which .NET Framework applications, components, and
controls are built.
Windows only
In this presentation we will discuss methods primarily from the following
namespaces
System.DirectoryServices
System.Data
System.Drawing
System.Net
System.DateTime
System.IO
System.Text
System.Math
System.Web
System.Diagnostics
System.Threading
Microsoft.VisualBasic
Progress and .NET
Progress provides a “Bridge” into the .NET Common Language Runtime
(CLR)
Originally intended just for UI design
Available since V10.2B
Only Prowin32.exe in 10.2B
Prowin32.exe, _Progres.exe, _Proapsv.exe all work in V11+
Developer Studio supports code completion for .NET classes
The Developer Studio Class Browser is also very useful
Data Mapping
By and large, Progress will map data to and from the .Net world
automatically
System.String, System.DateTime, System.Double etc. can be directly
assigned to Character, Date-Time and Decimal Progress variables
Binary data in .NET is often represented in memory as a System.Byte[].
Binary data in Progress is represented in memory as a MEMPTR
.NET write to a file, then COPY-LOB from file to Progress? – Not optimal
We need a means to change a System.Byte[] to a MEMPTR and back
without writing a file.
ByteArrayToMemptr and MemptrToByteArray are two methods I’ll be
using in a class I’ve named PugUtil. I use these in some of the demos.
The USING statement
Acts kind of like PROPATH does to access your Progress source
I find that while it saves a lot of typing, there’s a little less readability
These two code fragments behave exactly the same
USING System.*.
METHOD PUBLIC DECIMAL GetLeftBaseRadianAngle( ):
DEFINE VARIABLE sinX AS DECIMAL NO-UNDO.
sinX = GetHeight() / m_leftLeg.
RETURN Math:Round(Math:Asin(sinX),2).
END METHOD.
METHOD PUBLIC DECIMAL GetLeftBaseRadianAngle( ):
DEFINE VARIABLE sinX AS DECIMAL NO-UNDO.
sinX = GetHeight() / m_leftLeg.
RETURN System.Math:Round(System.Math:Asin(sinX),2).
END METHOD.
Translating from C#
The online examples in C# are probably the easiest to translate into
Progress
Progress uses the colon character to reference methods, properties etc.
The name of the class uses periods just like .NET
public double GetLeftBaseRadianAngle()
{
double sinX = GetHeight()/m_leftLeg;
return System.Math.Round(System.Math.Asin(sinX),2);
}
METHOD PUBLIC DECIMAL GetLeftBaseRadianAngle():
DEFINE VARIABLE sinX AS DECIMAL NO-UNDO.
sinX = GetHeight() / m_leftLeg.
RETURN System.Math:Round(System.Math:Asin(sinX),2).
END METHOD.
More translations
The other c# “using” syntax
Two things are illustrated here, The using syntax and an extension class.
The using syntax limits the scope and causes the object to be disposed at
the end of the block. This may be required before the class actually
performs the desired action.
using (ZipArchive archive = ZipFile.Open(zipPath, ZipArchiveMode.Update))
{
archive.CreateEntryFromFile(newFile, "NewEntry.txt");
}
This is not really a full substitute for what “using” does. It does not limit
the scope and the dispose will not happen if an error occurs.
DEFINE VARIABLE archive AS ZipArchive.
archive = ZipFile:Open(zipPath, ZipArchiveMode:Update).
ZipFileExtensions:CreateEntryFromFile(archive, newFile,“NewEntry.Txt").
archive:Dispose().
The c# foreach statement
There is no language statement in Progress that’s like the c# foreach.
Used to iterate through collections.
Foreach.i from Mike at Consultingwerk Ltd. is a great substitute
foreach(CompilerError CompErr in results.Errors) {
// Do something with the CompErr object
}
{foreach.i CompilerError CompErr in results:Errors}
/* Do something with the CompErr object*/
End.
Casting
When translating C# code, you’ll often see syntax that changes one
object type to another type. This is called “Casting”
Progress uses the CAST function to do this
The objects must have an inheritance relationship
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
or
HttpWebRequest myHttpWebRequest = WebRequest.Create(url) as HttpWebRequest;
DEFINE VARIABLE myHttpWebRequest AS HttpWebRequest.
myHttpWebRequest = CAST(WebRequest:Create(url), HttpWebRequest).
Enumerations
Similar to named constants but checked at compile time
Progress can access .NET enumerations just like C# when you need to use
an enumeration as a parameter to a method.
If you need to do more with enumerations, you need to use the Progress
EnumHelper class. (Pre 11.6)
Allows equality comparison as well as Add, And, Complement, IsGreater,
Xor etc.
TempImage.Save(pFileName, ImageFormat.Tiff)
TempImage:Save(pFileName, ImageFormat:Tiff)
if response.StatusCode==HttpStatusCode.NotFound
IF Progress.Util.EnumHelper:AreEqual(response:StatusCode, HttpStatusCode:NotFound)
V11.6+ only….
IF response:StatusCode = HttpStatusCode:NotFound
Case Sensitivity
This will compile
USING MindFusion.Diagramming.*.
DEFINE VARIABLE myDiagram AS Diagram.
This will not. The first use of a class is case sensitive.
USING MindFusion.Diagramming.*.
DEFINE VARIABLE myDiagram AS diagram.
When in doubt, check for proper case. Better yet, always use the proper
case for .Net objects.
Progress Keywords, Table and Field Names
Some .Net class names conflict with Progress keywords
You need to use the full namespace name to reference a class like this
/* Won’t Compile */
USING System.Drawing.*.
SomeObject:Color = Color:Red.
/* Compiles OK */
SomeObject:Color = System.Drawing.Color:Red.
Collisions with table or field names, even abbreviated table or field
names, will cause the same problem. The Sports database has a
TimeSheet.DayRecorded field
/* Won’t Compile*/
Using System.Windows.Forms.*.
MESSAGE Day:Friday VIEW-AS ALERT-BOX.
/* Compiles OK */
MESSAGE System.Windows.Forms.Day:Friday VIEW-AS ALERT-BOX.
The Class Browser
The assemblies.xml file
In a brand new Workspace or Project, there is no assemblies.xml file
You can use any of the .NET classes you can see using the Class Browser
If you want to use classes you don’t see in the Class Browser, you need to
add references to assemblies.xml (but there is no assemblies.xml file)
If you create a form and add a control, an assemblies.xml will be
automatically generated. Or you can create one using the Assembly
References choice under the OpenEdge Tools menu
Many of the examples I’ll show required this to work
All classes that come with the .Net Framework are registered in the
global assembly cache (GAC). When adding a reference these are
available on the list of references shown by the tool.
Other classes (.Net dlls) can be added to the same folder as
assemblies.xml and added to the assemblies file as local references
Other Resources
Progress GUI for .NET Programming manual
Progress GUI for .NET Mapping Reference
Google (Example: “.Net Delete a file”)
Progress Communities
MSDN
3rd Party Tools I’ve found very useful
WinScp
— FTP and SFTP with folder synchronization
— Free
HTMLAgilityPack
— An HTML Parser
— Free
Chilkat bundle
— Dozens of tools for FTP, SFTP, Sockets, HTTP, Zip, Gzip, Tar, POP, SMTP, IMAP, Encryption and more
— $289
Watch out for the “Block” when these are downloaded from the Internet
Now the Demos
Code is not intended to represent “Best Practices”
No error checking
Mostly procedures for ease of demonstrating
No more slides
Hopefully, this will be enough to get you started
Programs in Demo
Sleep.p
— Uses System.Threading.Thread:Sleep to pause for n milliseconds. Alternative to Progress PAUSE that
has no effect on messages, keyboard buffer, type of session etc.
CheckCredentials.p
— Uses System.DirectoryServices and System.DirectoryServices.AccountManagement to validate user
credentials against a local machine or an Active Directory server.
getTimeZone.p
— Uses System.Timezone to determine if it’s daylight time and then to display the proper name of the
current timezone.
PassWdGen.p
— Uses System.Web.Security to generate a random password.
RegularExpressions.p
— Uses System.Text.RegularExpressions.Regex to perform a validation on an email address seeing if it
matches a regular expression. Splits a string into an array of the words in the string.
ValidateEmail.p
— Uses two different .Net classes to validate an email address.
Programs in Demo, continued
SystemIOPath.p
— Shows example of some of the file attributes available like the extension of a file, the generation of
a temp file name etc.
— Also shows getting the size of a file. Progress FILE-INFO fails to do this with files over 2gb.
ProcessDemo.p
— Uses System.Diagnostics.Process to get a list of all running processes, looks for a process with a
particular name, then kills it.
ProcessStart.p
— Shows how to start a process with parameters and to get the standard output or error back from the
process. Much more powerful than OS-COMMAND and no dos boxes pop up.
HttpUtilityDemo.p
— Uses System.Web.HttpUtility to UrlEncode and UrlDecode a string. Shows how to parse a NameValue pair list.
ParseDates.p
— Shows use of the System.DateTime.TryParse() method to get date values from a variety of character
strings in various formats.
ParseDecimal.p
— Demonstrates converting a number in exponential notation to a decimal.
Programs in Demo, continued
ParseTextFile.p
— Uses a class form the VisualBasic package to parse complex text files into an array of fields.
GetActiveDirProp.p
— Shows how to read Active Directory properties for a user.
ZipDemo.p
— Uses System.IO.Compression and System.IO to first delete and create folder. Then creates a zip file
from the content of a directory. It then extracts that zip file to another directory.
— It creates a new zip file and adds files one at a time. It then reads through the files in this zip file.
SQLDemo1.p
— Shows how to use the System.Data and Sytem.Data.SqlClient classes to read data from a SQL
Database and create temp-table records. Uses MS AdventureWorks db.
SQLDemo2.p
— While the end result is similar to the above program, this demo shows reading data from a SQL
database into a dynamically created Progress dataset. Illustrates that it’s possible to have a method
that takes a SQL query and returns a Progress dataset with no manual definitions of tables or fields.
HttpClientDemo1
— Shows basic use of the System.Net.Http class to make an http query and retrieve xml. Also shows
basic use of System.Xml to parse values from the XML using Xpath expressions.
Programs in Demo, continued
HttpClientDemo2.p
— Uses the Http Client to download a file from a URL. Shows easier way to build query string. Shows
use of System.Diagnostics.Process:Start to open a file in the default application.
HttpClientDemo3.p
— Uses the Http Client to make a SOAP request. Illustrates how to do an Http POST and add headers.
HttpRestDemo1.p
— Uses the Http Client to call a simple REST service. Also shows the use of the Progress READ-JSON
method to load the JSON result into a dynamic temp-table.
ExchangeAppt.p
— Creates an Appointment using the Microsoft Exchange Web Services API. Outlook is not required to
use this API.
DemoCompression.w
— Requires the Sports 2000 database with an extra field added to the customer table named
“blobfield”. Illustrates the use of the supplied PugUtil class to read and write compressed data to
the database.
SqlDbDemo.p
— Copies the entire contents of the Sports2000 database into a Progress dataset then creates an MSSql
database, duplicates the schema, then copies all the data. This should not be considered ready for
production use.
Programs in Demo, continued
ImageResizeReformat.p
— Uses the supplied ImageUtil class to open an image and save it in several different jpeg qualities,
and resize the image. Also shows how to retrieve and or add the image to a database field without a
temporary file.
CSharpCompiler.w
— Written in Progress, this .w allows you to write, syntax check and compile C# code. Has no known
practical purpose except to illustrate how deep the .Net framework goes.
SystemMath.p
— Illustrates the use of the System.Math class. Shows a RoundUp function, calculates the volume of a
sphere and calculates the hypotenuse and the angles of a right triangle.
WebClientDemo4
— Illustrates possible encoding issues when using the WebClient. Shows a method of getting UTF-8 data
into a LONGCHAR even if –cpinternal not set to UTF-8.
HttpRestDemo2.p
— Like HttpResrDemo1.p but uses pure progress to access the REST service. Alsao shows use of the
Progress JsonObject.