Sample steps for using OCRService

The following example shows the typical usage of the OCRService:

  • Build the workflow using AssistantApp.exe (or iTest or OmniPage Ultimate 19).

  • Save the workflow into a .xwf file.

  • Test its running capabilities in iTest (or OmniPage Ultimate 19).

    You should create workflows without naming input and output files. In this case the workflow displays dialog boxes (custom open and save dialogs) to request the actual file names. In the save dialog you can set all output converter specific settings (Converters.Text.<convertername>.<settingname>). Here you can save these settings into a setting file for the xwf to JobXML conversion.

  • Convert the xwf file into JobXML using the XWFToXML.exe command line tool.

    You can place any additional CSDK settings to the setting file. If /p command line parameters are specified for XWFToXML.exe, the given input and output files are replaced by macros $INPUT_FILE$, $OUTPUT_FILE$.

  • Place these JobXML files somewhere in the application folder structure.

  • In the Application change the runtime input ($INPUT_FILE$), output ($OUTPUT_FILE$) and response XML ($OUTPUT_XML$) file macros to the actual file names.

  • Read JobXML into a string and pass it to the Run() function and wait for the Done event and handle the response XML.

A similar way to use WorkflowXMLDesigner.exe for loading a XWF file and directly saving it in XML format.

Simple .NET C# Application for IWR usage

There is a sample IWR application project available with C# sources withCSDK. The default project folder depends on your CSDK edition:

  • 32-bit edition:

    C:\ProgramData\OmniPage\CSDK22\x86\Samples\WorkflowRunner\IWR

  • 64-bit edition:

    C:\ProgramData\OmniPage\CSDK22\x64\Samples\WorkflowRunner\IWR

Simple C++ Application for IWR

// OCRJob.cpp : Defines the entry point for the console application.
//
#include <atlbase.h>
#include <atlcom.h>
#include <atlstr.h>
#include <msxml2.h>
#pragma comment(lib, "msxml2")

#import "OCRService.exe" no_namespace named_guids no_smart_pointers raw_interfaces_only
class ATL_NO_VTABLE CServiceWithEvents :
	public CComObjectRootEx<CComMultiThreadModel>,
	public IOCRServiceEvents
{
public:
	CServiceWithEvents() : m_hEvent(NULL), m_hr(S_OK)
	{
	}
	BEGIN_COM_MAP(CServiceWithEvents)
		COM_INTERFACE_ENTRY(IOCRServiceEvents)
		COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
	END_COM_MAP()
	DECLARE_GET_CONTROLLING_UNKNOWN()
	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	void FinalRelease()
	{
	}
	STDMETHOD(Done)(BSTR strGUID, long lResult, SAFEARRAY* psaResults, SAFEARRAY*, SAFEARRAY*, SAFEARRAY*)
	{
		if (m_strGUID != strGUID)
			return S_OK;
		if (lResult || psaResults)
			m_hr = E_FAIL;
		SetEvent(m_hEvent);
		return S_OK;
	}
	STDMETHOD(Ping)(void)
	{
		return S_OK;
	}
	HRESULT Run(TCHAR* strFile)
	{
		GUID guid = GUID_NULL;
		HRESULT hr = S_OK;
		CComPtr<IXMLDOMDocument2> pXMLDOMDocument;
		CComPtr<IOCRService> pOCRSrvice;
		VARIANT_BOOL bSuccess = VARIANT_TRUE;
		CComBSTR strXML;
		DWORD dwCookie = 0;
		m_strGUID.Empty();
		m_hr = S_OK;
		m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (!m_hEvent)
			hr = AtlHresultFromLastError();
		if (SUCCEEDED(hr))
		{
			hr = CoCreateGuid(&guid);
			m_strGUID = CComBSTR(guid);
		}
		if (SUCCEEDED(hr))
			hr = CoCreateFreeThreadedMarshaler(GetControllingUnknown(), &m_pUnkMarshaler.p);
		if (SUCCEEDED(hr)) 
			hr = pXMLDOMDocument.CoCreateInstance(CLSID_DOMDocument);
		if (SUCCEEDED(hr))
			hr = pXMLDOMDocument->load(CComVariant(strFile), &bSuccess);
		if (SUCCEEDED(hr))
			hr = pXMLDOMDocument->get_xml(&strXML);
		if (SUCCEEDED(hr))
			hr = pOCRSrvice.CoCreateInstance(CLSID_OCRService, NULL, CLSCTX_LOCAL_SERVER);
		if (SUCCEEDED(hr))
			hr = AtlAdvise(pOCRSrvice, GetControllingUnknown(), IID_IOCRServiceEvents, &dwCookie);
		if (SUCCEEDED(hr))
			hr = pOCRSrvice->Run(strXML, CComBSTR(guid));
		if (SUCCEEDED(hr))
		{
			AtlWaitWithMessageLoop(m_hEvent);
			hr = m_hr;
		}
		if (dwCookie)
			AtlUnadvise(pOCRSrvice, IID_IOCRServiceEvents, dwCookie);
		if (m_hEvent)
			CloseHandle(m_hEvent);
		m_pUnkMarshaler.Release();
		return hr;
	}
	CComPtr<IUnknown> m_pUnkMarshaler;
	HANDLE m_hEvent;
	HRESULT m_hr;
	CComBSTR m_strGUID;
};
int _tmain(int argc, _TCHAR* argv[])
{
	if (argc < 2)
		return E_FAIL;
	HRESULT hr = S_OK;
	CoInitialize(NULL);
	{
		CComObjectStackEx<CServiceWithEvents> service;
		hr = service.Run(argv[1]);
	}
	CoUninitialize();
	return hr;
}

Sample Workflow XML

This Workflow XML is created with Workflow XML Designer.

<?xml version="1.0" encoding="utf-8"?>
<!--This xml will be sent to OCRService.-->
<!--The xml is case sensitive.-->
<!--"type" attibutes determine the interpretation of "value" attributes.-->
<!--If "type" is an exported enum, then symbolic values can be applied.-->
<OCRJob>
  <!--clsid: identifies "Workflow" job item type.-->
  <!--id: the runtime identifier of this job item instance.-->
  <!--This job item will be started immediately.-->
  <!--"Workflow" job item executes a standard OmniPage workflow.-->
  <!--The number of the available steps is limited.-->
  <JobItem clsid="{14ABDDC9-0DF7-4D1C-9687-0AE5F2AD1C3D}" id="{4ff62635-f198-4804-9288-524600bdd588}">
    <!--Definition of the steps in the workflow.-->
    <Type type="integer" value="IWFT_WFS_DIRECT|CWFF_LOADIMG| CWFF_RECOGNIZE| CWFF_EXPORTDOC" />
    <!--Definition of the input files.-->
    <!--Input files are always passed in an array.-->
    <Inputs type="array">
      <Input type="string" value="$inputfile1$" />
    </Inputs>
    <!--Definition of the Workflow's parameters.-->
    <!--Each parameter is defined with "parametername", "type" and "value".-->
    <!--Default values are not transmitted.-->
    <!--For available parameters see OmniPageCSDK.IproPlus.WFStepParameters class.-->
    <Parameters>
      <!--Turn deskew for loading on / off.-->
      <Parameter parametername="SP_LDI_DESKEW" type="boolean" value="false" />
      <!--Specify page rotation for loading.-->
      <Parameter parametername="SP_LDI_PAGEROTATION" type="integer" value="ROT_NO" />
      <!--Specify Vertical Dictionaries.-->
      <Parameter parametername="SP_RCI_PROFDICT" type="array">
        <Parameter type="string" value="English Medical Dictionary" />
        <Parameter type="string" value="English Financial Dictionary" />
        <Parameter type="string" value="English Legal Dictionary" />
      </Parameter>
      <!--Whether to prompt for appending if the file exists at export.-->
      <Parameter parametername="SP_EXP_APPENDPROMPT" type="boolean" value="true" />
    </Parameters>
    <!--Definition of the Document's settings.-->
    <!--Each setting is defined with "settingname", "type" and "value".-->
    <!--For details see the CSDK documentation.-->
    <Settings>
      <!--See kRecSetDefaultRecognitionModule.  -->
      <Setting settingname="Kernel.OcrMgr.DefaultRecognitionModule" type="integer" value="RM_OMNIFONT_PLUS3W" />
    </Settings>
    <!--Definition of the output file.-->
    <Output type="string" value="$outputfile1$" />
    <!--Definition of the converter used to generate output.-->
    <Converter value="Converters.Text.PDF">
      <!--Definition of the Converter's properties.-->
      <!--Each property is defined with "propertyname", "type" and "value".-->
      <!--Default values are not transmitted.-->
      <!--For details see the CSDK documentation.-->
      <Properties>
        <Property propertyname="ColorQuality" type="integer" value="R2ID_PDFCOLORQUALITY_LOSLESS" />
        <Property propertyname="Compatibility" type="integer" value="10" />
        <Property propertyname="Linearized" type="boolean" value="true" />
        <Property propertyname="UseMRC" type="integer" value="R2ID_PDFMRC_LOSLESS" />
      </Properties>
    </Converter>
    <!--This job item will NOT generate response XML!-->
  </JobItem>
  <!--clsid: identifies "Statistics" job item type.-->
  <!--id: the runtime identifier of this job item instance.-->
  <!--dependency: this job item will be started when the job item having id="{4ff62635-f198-4804-9288-524600bdd588}" finished.-->
  <!--"Statistics" job item returns the statistics of the document.-->
  <!--For details see OmniPageCSDK.IproPlus.Document.GetStatistics.-->
  <JobItem clsid="{69490304-CC87-476C-90C3-58B200F6303F}" id="{9d91b2c4-fc86-42b9-a066-686ccaa73330}" dependency="{4ff62635-f198-4804-9288-524600bdd588}">
    <!--Definition of the response XML.-->
    <OutputXML type="string" value="$xmlfile1$" verbose="true" />
  </JobItem>
</OCRJob>

Registrations for redistribution

In the redistribution, perform the following registrations in the provided order before running IWR:

regsvr32 iproplus.dll /s
regsvr32 ocrserver.dll /s
ocrserver.exe /regserver
ocrservice.exe /regserver

Uninstallation:

ocrservice.exe /unregserver
ocrserver.exe /unregserver
regsvr32 /u ocrserver.dll /s
regsvr32 /u iproplus.dll /s