Tuesday, 20 May 2014

How to run multiple versions of Syspro

If you are a Syspro developer, you may want to run multiple versions of Syspro on the same machine. This article describes how to install and switch between version 6.1 and 7.0 of Syspro.

Setup

You probably already have Syspro 6.1 (server) installed, plus Syspro 6.1's versions of Syspro WCF and Syspro Web Services, so we'll take that as the starting point.

Install Syspro 7.0 (server), but pay attention to the points below.

Installing Syspro 7.0 Web Services

When installing Syspro Web Services version 7, it will remove and replace version 6.1’s web services; that is OK; you will not need to re-install Syspro 6.1 web services to access Syspro 6.1 web services. You will be able to access both versions of web services with Syspro 7's web services... so long as you follow the steps below under "Switching between versions".

Installing Syspro 7.0 WCF

Installing Syspro 7 WCF will wipe out your Syspro 6 WCF installation, so the recommend procedure is:
  1. Backup your Syspro 6 WCF config file.
  2. Install Syspro 7 WCF.
  3. Re-install Syspro 6 WCF, but to a DIFFERENT directory.
  4. Re-configure Syspro 6 WCF using the config file you saved in step 1.
  5. Configure Syspro 7 WCF to use DIFFERENT ports to Syspro 6.1 WCF.

Switching between versions

From an elevated command prompt, unregister the Syspro 6.1 version of Encore.dll and register the Syspro 7 version, e.g.

cd /syspro61/base
regsvr32 /u encore.dll
cd /syspro7/base
regsvr32 encore.dll

Then you should be able to use Syspro 7’s web services – you will need to use the correct company code and the instance number for your Syspro 7 installation, of course.

You will not be able to access Syspro 6 while Syspro 7’s Encore.dll is registered; you must use the procedure in reverse to unregister Syspro 7's Encore.dll and register Syspro 6.1's Encore.dll.

Thursday, 15 May 2014

How to test your Syspro WCF Service

These are some basic tests you can use to check if Syspro's WCF Service is up and running.
  1. Open a web browser and go to a URL such as:

    http://example.com:97/SYSPROWCFService/Rest

    You should see something like this:

  2. Open a web browser and go to a URL such as:

    http://example.com:97/SYSPROWCFService/Rest/GetVersion

    You should receive a text file called GetVersion containing the version number of the WCF Service, e.g. 7.0.0.3.
  3. Can you ping the Syspro server (provided the Syspro server responds to ICMP ping requests)?
     
  4. Telnet to the server and port, then hit ENTER a few times, e.g.

    telnet example.com 99

    If you get this:

    Connecting To example.com...Could not open connection to the host, on port 99: Connection failed

    then you didn't get a connection at all. This could happen if you had the wrong port or IP address.

    However, if you got a clear screen, then when you hit ENTER the telnet session terminated, then you got a connection OK.

    "Actively refused" means that you got at least as far as a TCP Connect packet arriving at the named server.
     
  5. From an elevated command prompt (i.e. run CMD as Administrator), run this command:

    netstat -ano | findstr 9999

    where 9999 is the process number or port number you are interested in.
    You should see your process and port listed.
     
  6. Check the Event Log for any error messages: in the Event Viewer, look under Application and Services Logs / SYSPROWCF.

Monday, 21 April 2014

How to use XSD2Code for SYSPRO’s Business Objects

When you call one of SYSPRO’s API’s, called a Business Object, via a web service or COM or DCOM or WCF, you need to pass it some XML. That XML is defined in a couple of XSD files. Generating that XML can be done easily in C# or VB .Net using a tool such as XSD2Codewhich is available from http://xsd2code.codeplex.com/. (Note that for Visual Studio 2012, you need XSD2CODE Beta Version 3.5 or later.)
The advantage of using a C# object rather than coding your XML as one big string is you get the advantages including:
  • Intellisense in Visual Studio – it shows you descriptions about each XML element from the XSD file’s annotations
  • Type safety
  • Easier to code: you don’t have to convert your types to strings, nor worry about maximum lengths etc. – it’s all done for you.
( I also tried using Microsoft’s XSD.exe tool, but found XSD2Code to be far superior – it is more configurable and so can be made to fit SYSPRO.)
These instructions are written for XSD2Code version 3.4 with Visual Studio 2010 and SYSPRO 6.1.
  1. Download and install XSD2Code. It integrates naturally with Visual Studio.
  2. From the <SYSPRO installation directory>/BASE/SCHEMAS directory,  add the XSD files for your desired business object into your project. E.g. to call the SORTOI business object, add C:\Syspro61\Base\Schemas\SORTOI.XSD and SORTOIDOC.XSD into your Visual Studio Project. Actually, I prefer to copy the XSD files into the appropriate sub-directory of my Visual Studio project and then add them from there, so that I can put the XSD files under source code control. (I use Mercurial.)
  3. In the Visual Studio Solution Explorer, right-click on the new XSD file and select Run XSD2Code Generation.
  4. Set the following parameters; the rest can stay as their default values. This is the key bit:
    1. PropertyParams/GeneratePropertyNameSpecified must be None, otherwise you won’t get parameters generated unless you set the correspondingfieldSpecified to true.
    2. Set the Code/NameSpace to <your-namespace> + the XSD name, so that there aren’t clashes with other XSD’s that use the same internal variables. E.g. I set mine to Syspro.Base.Schema.SORTOI and Syspro.Base.Schema.SORTOIDOC.
    3. Set the Code/TargetFramework to Silverlight or Net40 as appropriate.
    4. Leave the Serialization/DefaultEncoder as UTF-8.
    5. Set Serialization / Enabled to True. This saves you having to write your own serialization routine.
    6. Set Serialization / GenerateXMLAttributes to True.
  5. Press the Generate button.

Here is a screen shot of settings to use if you are using XSD2Code version 3.5:

Group your files
In the Visual Studio Solution Explorer, to have the newly generated .cs file (e.g. SORTOI.designer.cs) grouped under the XSD file (e.g. SORTOI.XSD), i.e. as a branch UNDER the XSD file instead of as a sibling file, follow these instructions:
  1. Close Visual Studio.
  2. Edit the .csproj file for that project with a text editor (such as vim or Notepad).
  3. Add DependentUpon tags (and open and close the Compile tag).
    E.g. change this line:
    <Compile Include="Schema\SORTOI.designer.cs" />
    to this:
    <Compile Include="Schema\SORTOI.designer.cs">
    <DependentUpon>SORTOI.XSD</DependentUpon>
    </Compile>

Use Namespaces

Note that when you tell XSD2Code what namespace to use, you need to use a different namespace for each XSD file as many of SYSPRO’s XSD files use properties with the same name, and you need to avoid those names clashing.
For example, for SOIRTOI.XSD, you could use a namespace of Syspro.Base.Schema.SORTOI;
for SORTOIDOC.XSD, you could use a different namespace such as Syspro.Base.Schema.SORTOIDOC.In other words, don’t use the same namespace for all your business objects. 
Then, in your C# code, you can add a reference to your Syspro.Base.Schema project, and you might like to write using statements such as these:
using SORTOI = Syspro.Base.Schema.SORTOI;
using SORTOIDOC = Syspro.Base.Schema.SORTOIDOC;
Then you will be able to access the generated objects with minimal namespace paths in your code.

Generate your XML

Now you can create code your XML settings using plain old C# objects as simply as this example:
var SORTOI_Parameters = new SORTOI.PostOrders()
{
 Parameters = new SORTOI.Parameters()
 {
     ValidateOnly = PORTOI.ValidateOnly.Y,
     StatusInProcess = PORTOI.StatusInProcess.N
 }
};

Edit the code to correct List definitions

Some List definitions in SYSPRO’s XSD files don’t seem to be properly declared, so you may have to manually edit the generated code and find all lines that begin with public List and add a line like this above the declaration (change the parameter on the right to match your type):
[System.XML.Serialization.XmlElementAttribute("Item")]
so that the final code looks like this example:
[System.Xml.Serialization.XmlElementAttribute("Item")]
public List<SetupQotNonStockItem> Item
This problem only occurs for certain XSD files (such as WIPTPBDOC.xsd), where-as others such as PORTOIDOC.xsd have perfectly-generated code. My guess is that some of SYSPRO’s XSD files are not well constructed.
(Note that XSD2Code’s GenerateXMLAttributes option creates these XmlElementAttributes automatically… if the XSD code is correct.)

Sometimes the XSD file is incorrect

Sometimes the XSD file is actually incorrect. I am getting such problems reported and corrected if and when I find them. See this forum post for more information.

If you right-click on the XSD file but can’t see “Run XSD2Code generation”

If you right-click on your XSD file but can’t see Run XSD2Code generation enabled, this may be because the highlighted file has just switched to a different file, due to some behaviour in Visual Studio. To work around this, double-click on your XSD file first so that it comes up for editing; then you will be able to right-click on the XSD file and generate code for it.

Serialize your objects

To convert your object to XML, you can use code such as this:
string XmlParameters = SORTOI_Parameters.Serialize();

Syspro’s VBScript Business Objects don’t like namespace declarations

Note that if you may have XML Namespace declarations in your XML from serialization like this:
<Orders xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""">
This shouldn’t be a problem BUT if you are passing this XML to Syspro’s VBScript and then calling a Business Object from VBScript, it will not like the xmlns declaration, so you may want to add this code on the VBSCript side (see related article, How to invoke a Syspro VBScript function from a .Net User Control):
Dim nameSpaceDeclaration
nameSpaceDeclaration = "xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"""
XmlParameters = Replace(XmlParameters, nameSpaceDeclaration,"")
This was the case for Syspro 6.1 Port 69.
However, this doesn’t seem to be an issue if calling the Business Object not from VB Script but from a web service or via DCOM.

Adjust the encoding for Silverlight

If you are using this in Silverlight, you may need to adjust the XML encoding; this is an ugly way of doing it:
XmlParameters = XmlParameters.Replace("encoding=\"utf-8\"", "encoding=\"Windows-1252\"");
A better way of doing this may be to pass the Serialize routine a parameter to select which encoding to use; I have yet to try this.

Finally

Then you can pass those XML strings to the web service for the business object, e.g:
setupProxySORTOI.AddAsync(userId, "SORTOI", XMLParameters, XMLIn);

See Also