# OxSvrSpt

## General Description

The library `OxSvrSpt.dll` provides access to server functionality via a
Microsoft-COM interface. The focus is on easy handling by the user and VB- and scripting-conform COM interfaces.
The easy-to-use approach is used, which allows simple calls to be performed with few
code lines. In multithreading applications, care must be taken that thread coordination regarding the execution of actions via OxSvrSpt is performed.

The following properties are supported:

* Error handling via COM error (IErrorInfo)

* All occurred errors are thrown as COM errors. If a method call returns multiple errors
(z. B. calling a server job), the first error is thrown as a COM error
and the remaining errors are available in a collection.

* Transparent use of Base64 parameter

* The processing of the Base64 parameter of the server is completely taken over by OxSvrSpt.
For this purpose, stream and XML access methods are provided to the user.

* Automatic encoding and decoding of binary parameters (BASE64)

* The data passed by the user to the OxSvrSpt library is automatically encoded for transmission to the server in MIME-BASE-64 and decoded when retrieving data from the server.
The user no longer comes into contact with the encoding.

* Encoding and decoding of XML data by library

* Through the XML properties of the parameter and FileParameter interfaces, there is the
possibility to read and set the basic string representation (BSTR) of XML data.
The OxSvrSpt library takes care of the correct encoding and decoding into the
corresponding binary representation (UTF-8, UTF-16, ...). The stream methods of these
interfaces also provide the possibility to process the data directly via an IStream interface. It is therefore possible, for example, to load parameters directly into an
MSXML-DOM document or take them from such a document.

* Automatic encoding of password via module

* For login, there is the option to pass the password encoded or unencoded.
The necessary conversion for transmission to the server is taken over by the OxSvrSpt library.

A configured two-factor authentication is not included.

* Collections that can be used with ForEach

* All COM collections are ForEach-capable. This makes it possible to iterate from Visual Basic,
scripting environments and .net through these.

* Correct processing of collections and parameters in the debugger

* In debug environments that directly access the properties of COM objects and
display them (e.g. Visual Basic), it is ensured that the stream accesses used do not get disturbed.
The collections are VB-compatible, which makes it possible to view the elements in the VB debugger.

* Return parameters are created by the called property or method

* All return parameters are made available so that creation is done via a
method of the OxSvrSpt library. It is not necessary to pass a variable to fill into the library from a COM scripting environment.
The server object is the only creatable object except for the helper object. All other
interfaces are provided by this, or subordinate interfaces.

* Simple processing of notifications

* For processing notifications, an event interface is available that
takes over the processing of input and output parameters in an equivalent way to the job interface.

* Methods for reading and writing ASCII data from streams

* When trying to serialize basic character strings from Visual Basic or COM-based scripting environments, the data is processed as widechars. The methods provided allow reading and writing data that is not XML as ASCII from Base64 parameters.

## Modules

### Including the Library

This section shows the use of the `OxSvrSpt` library from different
programming languages. Depending on the programming language and
development environment used, the possibilities for accessing the library differ.

Visual Basic

To use `OxSvrSpt` via the type library, the enaio® server access library
must be included via the "References" menu item of the development environment.

Creation is done via the following code:
```vb
Private m_oServer As new OxSvrSpt.Server
```
The component can also be included using late binding. The source code for this
corresponds to the VB-Script code.

Visual Basic Script

In VB-Script, the server object can be created as follows:

```vbscript
Dim oServer
Set oServer = CreateObject( "OxSvrSpt.Server" )
```
Visual C++

For using the `OxSvrSpt` library in Visual C++, the use of the `import` directive is recommended. The following code snippet shows this import. This should be done at a
central location, e.g. `StdAfx.h`.
```cpp
#pragma warning ( disable: 4192 )
#import "OxSvrSpt.dll" raw_method_prefix("raw_") rename_namespace( "OxSvrSpt" )
#pragma warning ( default: 4192 )
```
For use, the `high` methods should be used instead of the `raw` methods. To avoid confusion, the `raw` functions are therefore provided with the prefix `raw_` in the above `import` directive. The `high` methods map COM errors
automatically to `_com_error` exception handling. In addition, these ensure that
passed basic character strings are of the correct type. The following code snippet shows
the direct use of a widechar string as a parameter, instead of a basic string. Since access to a basic string in C++ corresponds to a `WIDECHAR` string, this is compilable and works as long as the COM client and
the COM server are in the same apartment.

However, this should not be assumed!

Such a call can lead to hard-to-locate errors.
```cpp
HRESULT Test( BSTR Message );
...
HRESULT hr = Test( L"irgendwas" );
```
If instead of the `raw` method the `high` method is used, the `_bstr_t` class
takes care of correct processing.
```cpp
HRESULT Test(_bstr_t Message );
...
HRESULT hr = Test( L"irgendwas" );
```
Note:

When implementing `high` methods without `retval` return value, the `import` directive declares these methods as `HRESULT` instead of `void`. This `HRESULT` never returns
an error value, since in case of an error a `_com_error` exception is thrown. The structure of these
methods resembles that of the `raw` functions. For this reason, to avoid confusion, the `raw_method_prefix` should be used.

The creation of the object should be done via the constructor of the `IServerPtr` and not via the
`CreateInstance` method, since the latter does not throw a `_com_error` exception on failure. In this case, it is necessary to evaluate the `HRESULT` value yourself
to get a meaningful error message.

```cpp
try {
OxSvrSpt::IServerPtr spServer( __uuidof( OxSvrSpt::Server ));
}
catch ( _com_error& ex ) {
}
```
Alternatively, the creation of the `IServer` object can also be done via the name of the Co-class.
This corresponds roughly to late binding when creating objects in Visual Basic.

```cpp
try {
OxSvrSpt::IServerPtr spServer( "OxSvrSpt::Server" ));
}
catch ( _com_error& ex ) {
}
```
Microsoft C#

To use the component, the reference to enaio® server access library must be added in
Microsoft Visual Studio. For this, click on Project - Add Reference - COM . Then the namespace `OxSvrSpt` can be included with the `using` directive.

```csharp
Server server = new Server();
```

### Login

This section shows the use of the `ISession` object in different
programming languages. Login methods are presented with which you can log in using an
unencrypted and encrypted password, a session GUID and the NT user name to the enaio®-server.

Possibilities for login

To log into the system, an object of the class `IServer` must have been created. This
provides methods, such as `Login()`, which you can use to log in. Upon successful authentication, the methods return an `ISession` object. If
authentication fails, a COM exception is thrown. If you pass empty strings for the parameters " `username` " and " `password` ", then the library attempts to log in with the NT user. Automatic login is possible,
if this has been activated in enaio® administrator. NTLM authentication is not yet implemented.

* The `Login()` method is used to log in the specified user to the specified server.

* The `LoginGUID()` method is used to log in with an existing `SessionGUID`.

* The `LoginBalanced()` method is used to log in to a group of servers. Each
possible server in the list consists of the server name, port and weighting. The
weighting indicates with what probability the connection to the associated server
is established. The weights should not exceed 100 in total.

* The `OpenSession()` method is used to log in to an existing `DefaultSession`. `DefaultSessions` can be created using the previously described methods by setting the parameter `DefaultSession` to `True`.

Visual Basic and VB-Script

The `Login()` method receives the parameters " `username` ", " `password` ", " `server` " and
" `port` " as input. In this case, " `PasswordType` " and `DefaultSession` are automatically set to
`false`.
```vb
Dim session As session
' Login of a user to the specified server
Set session = server.Login("root", "optimal", "localhost", "4000")
' Login via an existing SessionGUID
Set session = server.LoginGUID("D57D21256EFB4C91B79EDD5A4928400B", "localhost",
"4000")
' Login of a user to a group of servers
Set session = server.LoginBalanced("root", "optimal",
"localhost#4000#90;10.1.3.100#4600#10")
```
Visual C++

In C++, the parameters " `PasswordType` " and " `DefaultSession` " cannot be omitted,
since C++ does not support default values. The following examples show login
with an encrypted password.
```cpp
OxSvrSpt::ISessionPtr spSession = spServer->Login("root", "HB016016116515215614215500000000000000000000000000", "localhost", "4000", OxSvrSpt::PasswortTypeEnum::pwEncrypted, false );

OxSvrSpt::ISessionPtr spSession = spServer>LoginGUID("D57D21256EFB4C91B79EDD5A4928400B","localhost", "4000", false );

OxSvrSpt::ISessionPtr spSession = spServer->LoginBalanced("root", "HB016016116515215614215500000000000000000000000000", "localhost#4000#90;10.1.3.100#4600#10",OxSvrSpt::PasswortTypeEnum::pwEncrypted, false );

OxSvrSpt::ISessionPtr spDefaultSession = spServer->Login("root", "HB016016116515215614215500000000000000000000000000", "localhost", "4000", OxSvrSpt::PasswortTypeEnum::pwEncrypted, true );

OxSvrSpt::ISessionPtr spSession = spServer->OpenSession((bstr_t)spDefaultSession->Properties->Item["SessionGUID"]->Value, OxSvrSpt.OpenSession);
```
Visual C#

In C#, the parameters " `PasswordType` " and " `DefaultSession` " cannot be omitted.
In this example, login with the NT user name should be made, which is why
empty strings are passed for the parameters " `username` " and " `password` ".

```csharp
Session session = server.Login("","","localhost", "4000", PasswortTypeEnum.pwNotEncrypted, false );

Session session = server.LoginGUID("D57D21256EFB4C91B79EDD5A4928400B","localhost", "4000", false );

Session session = server.LoginBalanced("", "", "localhost#4000#90;10.1.3.100#4600#10", PasswortTypeEnum.pwNotEncrypted, false );

Session defaultSession = server.Login("root","optimal","localhost", "4000", PasswortTypeEnum.pwNotEncrypted, true );

Session session = server.OpenSession(defaultSession.Properties["SessionGUID"].Value.ToString(), "OxSvrSpt.OpenSession");
```

### License Management

For checking and using licenses, the `ILicenses` collection is available in the `ISession` object. Through this, the licenses to be used on the server
can be logged in, logged out and checked. All logged-in licenses are kept in the
collection.
```javascript
/*
JavaScript version
This enables the use of COM exceptions compared to the VBS version. When an error occurs, the program flow
is interrupted and jumps to error handling.
*/
try
{
var oServer, oSession, oJob;
oServer = new ActiveXObject( "OxSvrSpt.Server" );
oSession = oServer.Login( "root", "optimal", "localhost", "4000" );
oSession.Licenses.Add( "ASC" );
oSession.Licenses.Delete( "ASC" );
oSession.Licenses.Add( "ASC" );
WScript.Echo( "ok" );
}
catch( ex )
{
WScript.Echo( ex.description );
}
```

### Server Events

Description

You have the option to be informed by the server about certain events via `Notifications`.

VB

In Visual Basic, `Notifications` are available through the event mechanism as shown in
the following example.

```vb
Private WithEvents m_oSession As OxSvrSpt.Session
Private m_oServer As OxSvrSpt.Server
public sub Start()
    m_oServer.Properties("NotifyNeeded") = True
    Set m_oSession = m_oServer.Login(,, "localhost", "4000")
    end sub
    Private Sub m_oSession_Notify(Job As OxSvrSpt.INotifyJob)
    On Error GoTo ErrTrap
    Dim strFileXML As String
    strFileXML = Job.InputFileParameters(1).XML
    ' Return parameters
    Job.OutputParameters.AddNewIntegerParameter "test", 100
    Job.OutputParameters.AddNewStringParameter "meier", "huhu"
    Exit Sub
    ErrTrap:
    MsgBox Err.Description
    End Sub
```
VBScript

If you want to use `Notifications` in a scripting host environment (VB-Script as vbs), you must create the instance via the `CreateObject()` method of the `WScript` environment.
```vbscript
Dim oServer
Set oServer = WScript.CreateObject( "OxSvrSpt.Server", "oServer_" )
```
If the `IServer` object is created via the `WScript` host, there is the option to specify a prefix for
event functions. Through this mechanism, the `Notifications` can be caught.

Furthermore, the `Callback` functionalities of the `OxSvrCom` library are available through the methods
`CreateJobSink()` and `CreateJobSink()` of the `ISession` interface.

```vbscript
Dim oServer, oSession
Set oServer = WScript.CreateObject( "OxSvrSpt.Server", "oServer_" )
' Notifications should be used
oServer.Properties("NotifyNeeded") = True
' Use auto-login
Set oSession = oServer.Login( "", "", "localhost", "4000" )

' ...

'
' This function is called by the server object when a notification arrives
' within the specified idle time.
'
' @param oJob
'   Contains the data for calling the notification.
'   This corresponds to the job object of the session. The only
'   difference is that instead of input parameters, output parameters are used
'   to create parameters.
'
Sub oServer_Notify( oJob )
    Dim strText
    ' Display name of notification
    strText = "Name: " & oJob.Name & vbCrLf
    ' Display all input parameters
    strText = strText & " Parameter: " & vbCrLf
    Dim oParameter
    For Each oParameter In oJob.InputParameters
        strText = strText & "  " & oParameter.Name & " - " & _
            CStr( oParameter.Value ) & vbCrLf
    Next
    ' Write result to a text box
    MsgBox strText
End Sub
```

### XML Processing

Depending on the XML encoding used, the XML data differs in its binary representation.

Example for determining object definition

JavaScript version

```javascript
/*
JavaScript version
This enables the use of COM exceptions compared to the VBS version. When an error occurs, the program flow
is interrupted and jumps to error handling.
*/
try
{
var oServer, oSession, oJob;
oServer = new ActiveXObject( "OxSvrSpt.Server" );
oSession = oServer.Login( "root", "optimal", "localhost", "4000" );
oJob   = oSession.NewJob( "dms.GetObjDef" );
oJob.InputParameters.AddNewIntegerParameter( "Flags", 0 );
oJob.Execute();
WScript.Echo( oJob.OutputFileParameters(1).XML );
}
catch( ex )
{
WScript.Echo( ex.description );
}
```
VB-Script version
```vbscript
Option Explicit
Dim oServer, oSession, oJob,o
Set oServer = CreateObject( "OxSvrSpt.Server" )
set oSession = oServer.Login( "root", "optimal", "localhost", "4000" )
set oJob   = oSession.NewJob( "dms.GetObjDef" )
oJob.InputParameters.AddNewIntegerParameter "Flags", 0
oJob.Execute
msgbox oJob.OutputFileParameters(1).XML,,"Object definition"
```

### Binary Data Processing

For processing binary data in input and output parameters, several options are available. Both the `IParameter` - and the `IFileParameter` -objects provide two different methods for this.

* 1. Access via chunks (byte arrays)

* 2. Access via a stream ( `IStream` )

```vbscript
'
' Example script to read binary data byte by byte via the
' GetChunk method of a parameter.
'
Option Explicit
Dim oServer, oSession, oJob, oFileParameter
Set oServer = CreateObject("OxSvrSpt.Server")
set oSession = oServer.Login("root", "optimal", "localhost", 4000)
Set oJob   = oSession.NewJob("dummy")
Set oFileParameter = oJob.InputFileParameters.AddTempFile()
oFileParameter.xml = "<?xml version='1.0' encoding='utf-16' ?><abc>äöü</abc>"
' Set stream to beginning position
oFileParameter.ResetStream
Dim abReadData
abReadData = oFileParameter.GetChunk(oFileParameter.ActualSize)
Dim cPos
For cPos = LBound(abReadData) + 1 To UBound(abReadData)
Dim bData
bData = Ascb(Midb(abReadData, cPos, 1))
WScript.Echo(cPos & ":" & bData)
next
WScript.Echo("finished")
```

### Error Handling

In all error cases, the `OxSvrSpt` library throws a COM error. In addition, the errors are also added to the `IError` collection in both the `IServer` - and the `IJob` -objects. In both cases, it is possible that more than one error is returned.
The COM error corresponds to the first error in the `IError` collection.

### Structure Plan

The following diagrams show the structure of OxSvrSpt:

Legend for the flowchart

`OxSvrSpt` library

`Session` object

`Job` object

`Properties D` collection

`Licenses` collection

`OutputParameters D` collection

`InputParameters` collection

`OutputFileParameters` collection

`InputFileParameters` collection

`Errors` collection

`Parameter` object

`FileParameter` object

### Attaching Watermarks to PDF Documents

In addition to the watermark printing designation of PDF documents via
the settings in enaio® administrator, there is the possibility to attach watermarks using extended capabilities. For this, the target format 'pdf' must be specified and the
`Job` parameter 'Watermark' set to 1. All following parameters consist of a prefix
and a postfix, where the parameter `'HeaderText'` has the prefix `'Header'` and the postfix
`'Text'`. The parameters are described in detail below:

Four areas can be defined for text input with the following parameter prefixes:
'Header', 'Footer', 'Side' and 'Center'.

The following parameter postfixes are possible, each of which must use one of the above prefixes. All parameter postfixes are optional, but at least one ' `*Text` ' parameter must be specified so that the extended watermark is applied,
otherwise the enaio® administrator settings are used. The postfixes are listed below:

Text (STRING):

Text to be applied. If no text is specified, all other entries for the
corresponding watermark type are ignored and no text is applied.

The following replacement variables are possible in the specified text:

Variable Description

`#TIME#` current time

`#DATE#` current date

`#USER#` username

`#USER-FULL#` full username

`#COMPUTER-IP#` IP address

`#COMPUTER-GUID#` GUID of computer

`#COMPUTER-NAME#` name of computer

TextColor (INT):

0 – 7 (default is 0) with the following values:
Value Description

0 Black

1 White

2 Yellow

3 Red

4 Green

5 Magenta

6 Cyan

7 Blue

Alternatively:

TextColorRGB (STRING): 0-255,0-255,0-255 (R,G,B values for a color separated by comma)

Font (STRING): Helvetica…, Times…, or Courier… (default is Helvetica)

FontBold (INT): 0 or 1 ( 1-> Bold, 0 -> Standard)

FontItalic (INT): 0 or 1 ( 1-> Italic, 0 -> Standard)

FontSize (INT): Font size in points (default is 10)

The following parameters can be used to set the position of the text:

Position (INT): 0-8 (default is 0) for 'Header' 0, for 'Footer' 1, for 'Side' 4 and for 'Center' 8

Value Description

0 Top-left

1 Bottom-left

2 Top-right

3 Bottom-right

4 Center-left

5 Center-right

6 Center-top

7 Center-bottom

8 Center-center

OffsetX (INT): (default is 0) Offset in mm relative to left edge of sheet.

OffsetY (INT): (default is 0) Offset in mm relative to top edge of sheet.

PlaceType (INT): 0-2 (default is 0) 0 -> All pages, 1 -> odd pages, 2-> even pages

FillStyle (INT): 0-2 (default is 0) 0 -> Filled, 1 -> shadow outline, 2 -> filled shadow outline

Angle (INT): 0-360 (default is 0) Rotation in degrees

Example of a call:
```vbscript
Set oServerJob = o.CreateServerJob("cnv.ConvertDocument")
oServerJob.AddFile "myfile" (file to be converted)
oServerJob.AddInputParameter "DestinationFormat", "pdf", 1
oServerJob.AddInputParameter "HeaderText", "Header line", 1
oServerJob.AddInputParameter "HeaderFont", "Courier", 1
oServerJob.AddInputParameter "HeaderFontSize", "10,0", 4
oServerJob.AddInputParameter "HeaderTextColor", "3", 2
oServerJob.AddInputParameter "FooterText", " Created by #USER#, #DATE#,
#TIME#", 1
oServerJob.AddInputParameter "FooterFontSize", "14,0", 4
oServerJob.AddInputParameter "FooterFontBold", "1", 2
oServerJob.AddInputParameter "FooterFontItalic", "1", 2
oServerJob.AddInputParameter "FooterTextColorRGB", "255,0,0", 1
```
Note: Instead of prefixes 'Header' and 'Footer' as in this example, 'Side' or 'Center'
are also possible.

Example for positioning with type 'Center':
```vbscript
oServerJob.AddInputParameter "CenterAngle", "45", 2
oServerJob.AddInputParameter "CenterOffsetX", "-10", 2
oServerJob.AddInputParameter "CenterOffsetY", "10", 2
oServerJob.AddInputParameter "CenterPlaceType", "1", 1
oServerJob.AddInputParameter "CenterFillStyle", "2", 1
```
Note: Care must be taken to observe case sensitivity. ( `Job` parameters are generally
case sensitive).

## Data Structures

* [IError](oxsvrspt/IError.md)
* [IErrors](oxsvrspt/IErrors.md)
* [IFileParameter](oxsvrspt/IFileParameter.md)
* [IHelper](oxsvrspt/IHelper.md)
* [IInputFileParameters](oxsvrspt/IInputFileParameters.md)
* [IInputParameters](oxsvrspt/IInputParameters.md)
* [IJob](oxsvrspt/IJob.md)
* [ILicenses](oxsvrspt/ILicenses.md)
* [ILogger](oxsvrspt/ILogger.md)
* [INotifyErrors](oxsvrspt/INotifyErrors.md)
* [INotifyInputFileParameters](oxsvrspt/INotifyInputFileParameters.md)
* [INotifyInputParameters](oxsvrspt/INotifyInputParameters.md)
* [INotifyJob](oxsvrspt/INotifyJob.md)
* [INotifyOutputFileParameters](oxsvrspt/INotifyOutputFileParameters.md)
* [INotifyOutputParameters](oxsvrspt/INotifyOutputParameters.md)
* [IOutputFileParameters](oxsvrspt/IOutputFileParameters.md)
* [IOutputParameters](oxsvrspt/IOutputParameters.md)
* [IParameter](oxsvrspt/IParameter.md)
* [IProperties](oxsvrspt/IProperties.md)
* [IProperty](oxsvrspt/IProperty.md)
* [IServer](oxsvrspt/IServer.md)
* [ISession](oxsvrspt/ISession.md)

## Class Hierarchy

* `_INotificationEvent`

* `IError`

* `IErrors`

* `INotifyErrors`

* `IFileParameter`

* `IHelper`

* `IInputFileParameters`

* `INotifyOutputFileParameters`

* `IInputParameters`

* `INotifyOutputParameters`

* `IJob`

* `ILicenses`

* `ILogger`

* `INotifyJob`

* `IOutputFileParameters`

* `INotifyInputFileParameters`

* `IOutputParameters`

* `IInputParameters`

* `IParameter`

* `IProperties`

* `IProperty`

* `IServer`

* `ISession`
