Monday 21 April 2014

How to invoke a SYSPRO VBScript function from a .Net User Control

If you are invoking a SYSPRO VBScript function from a .Net User Control on a Custom pane, there are a number of traps to avoid that aren’t explicitly stated in the otherwise very helpful document, Using .Net User Controls in 6.1 on the SYSPRO Support Zone.

Your delegate must be in the same namespace

Your delegate that calls doRefresh must be in the same namespace as the control linked to the customized pane. (This isn’t explicitly stated in the version of the documentation published 08 June 2010, although the converse situation is mentioned in the section, “Invoking methods on the User Control from a SYSPRO form”.)

Parameter values must be able to become valid VBScript

The value being passed as a parameter to doRefresh must compile as standard VBScript, i.e.:
  • if it contains any double quotes, they must be escaped as two double quotes. Even better, on the .Net side, just encode any double quotes as a non-printable character such as CTRL+C, then on the VBScript side, do the reverse.
  • if it contains any new lines, they must be removed.
The parameter which becomes the RefreshValue in VBScript CAN be of unlimited length (contrary to what I first wrote here).
Here is some example code for the DotNet side to safely encode double quotes and new lines:
private static string MakeSafeForVBScript(string sourceString)
{
 // The VB Script will essentially do a statement like this:
 // Dim RefreshValue : Refreshvalue = "<?xml version="1.0" encoding="Windows-1252"?>
 // However, it will give a syntax error on any embedded double quotes or new lines,
 // so convert new lines into CTRL+B,
 // and convert double-quotes into CTRL+D.

 string newLineReplacement = ((char)0x2).ToString(); // CTRL+B
 const char doubleQuoteReplacement = (char)0x4; // CTRL+D
 const char doubleQuote = '"';

sourceString = sourceString.Replace(doubleQuote, doubleQuoteReplacement).Replace("\r\n", newLineReplacement);

 return dotNetVariable;

}
Here is an example VBScript code snippet; it puts the double-quotes and new lines back:
Function Unencode (encodedString)
 Dim control_B
 Dim control_D
 Dim doubleQuote
 Dim newLine
 Dim result

 control_B = Chr(2)
 control_D = Chr(4)
 doubleQuote = Chr(34)
 newLine = chr(13) & chr(10) ' \r\n, i.e. CTRL+M CTRL+J.
 encodedString = Replace(encodedString, control_D, doubleQuote)

 Unencode = Replace(encodedString, control_B, newLine)

End Function

GetApplicationInfo and GetSysproInfo don’t always return pure XML

Note that returned XML from GetApplicationInfo or GetSysproInfo does NOT always contain valid XML, because it sometimes contains embedded double quotes, so you have to  escape those quotes before passing the returned value into an XML parser.
E.g. the returned XML may contain a fragment like this:
<DiagnosticAppPath Value="""C:\SYSPRO61\BASE\IMPACT.EXE"""/>
This needs to become (note the backslashed quotes):
<DiagnosticAppPath Value="\"C:\SYSPRO61\BASE\IMPACT.EXE\""/>
You can use the following C# code to sort out the embedded quotes:
String tripleQuotes = @"""""""";
String singleQuoteBackslashedQuote = @"""";
var fixedQuotes = systemVariables.Replace(tripleQuotes, singleQuoteBackslashedQuote);

Remove XML NameSpace declarations

Also note that Syspro’s Business Objects called from SYSPRO’s VBScript doesn’t like XML that has namespace declarations; see How to use XSD2Code for Syspro Business Objects for more details. (Calls to SYSPRO’s Business Objects via Web Services or DCOM don’t seem to have this problem.)

Conclusion

After sorting these things out, you should be ready to run.

No comments:

Post a Comment