Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel
By Sprezz | Thursday, 24 November 2022 14:42 | 0 Comments

Recently, a client was a little late in applying their authorisation code to their copy of OI10, and attempts to access OI were met with error messages "PSSI.66: ???". This seemed a strange message and at first we suspected that it wasn't even an OI message.

However chatting to the Rev developers, it seems that an insert (PS_RESOURCES) was missing from SYSENV and that it should in fact have had the following values 

///////////////////////////////////////////////////////////////////////////////

//[PS_SYSINTIALIZE]////////////////////////////////////////////////////////////

PSSI.00: No entry window defined for the %1% application.
PSSI.01: No visible entry window started for the %1% application
PSSI.02: Unable to start entry window "%1%" for the %2% application
PSSI.20: . Process aborted
PSSI.21: %1% initialization
PSSI.60: This Developer Class Server Deployment Pack for OpenInsight is due to expire on %1%.|Please contact Revelation Software at +1-800-262-4747 to renew your license.
PSSI.61: This copy of OpenInsight is due to expire on %1%.|Please contact Revelation Software at +1-800-262-4747 to renew your license.
PSSI.62: This copy of OpenInsight expired on %1%.|Use of this software is in violation of your OpenInsight Software License Agreement.|Please contact Revelation Software at +1-800-262-4747 to renew your license.
PSSI.63: This copy of OpenInsight has expired.||To purchase this product, contact Revelation Software on the web at:||www.revelation.com||Or call toll-free: (800) 262-4747
PSSI.64: This evaluation copy of OpenInsight expires on %1%.||To purchase this product, contact Revelation Software on the web at:||www.revelation.com||Or call toll-free: (800) 262-4747
PSSI.65: This evaluation copy of OpenInsight has expired.||To purchase this product, contact Revelation Software on the web at:||www.revelation.com||Or call toll-free: (800) 262-4747
PSSI.66: This Developer Class Server Deployment Pack for OpenInsight expired on %1%.|Use of this software is in violation of your OpenInsight Software License Agreement.|Please contact Revelation Software at +1-800-262-4747 to renew your license.
PSSI.67: Unable to process License Information.
PSSI.68: OpenInsight Licensing

So that clarified that issue.

The issue that we were left with was that normally in OI10, reauthorisation is done from within the product - and if you can't log in... you can connect the dots.

So, we went on search for a reauthorisation executable in the OI directory and not surprisingly found revauth.exe. This is a small executable, and clicking it seemed to do nothing. Until we realised that it was likely a command line executable. 

Invoking powershell, we moved to the UNC containing revauth.exe and executed it with a /?. These were the results.

PS Microsoft.PowerShell.Core\FileSystem::\\MyServer\Shares\Sprezz\programs\OINSIGHT_10> .\revauth.exe /?

revauth <featurename> <authcode> <filename>

values for <featurename>:

OI : OpenInsight
UDN: Universal Driver (network user license)
UDH: Universal Driver Heavy

So we instructed the client to run the following command

revauth OI AuthCode revengine.lic

and lo and behold, the system worked again!

As an aside, the licensing information is no longer stored encrypted in a DLL but rather is stored in the revengine.lic file where it can be easily viewed - a modified example is shown below.

<OI>
    <Signature>Wwe23-Pg478-6h295-k1q62-00j9W-7jij8</Signature>
    <SerialNumber>D99999999</SerialNumber>
    <NumUsers>250</NumUsers>
    <ExpirationDate>2023-10-17</ExpirationDate>
    <ExpirationType>1</ExpirationType>
</OI>

Of course, you can't alter any of these values in notepad as they are actually encoded into the signature, but nice try!

And for readers who aren't British and of a certain age...









By Sprezz | Saturday, 1 October 2022 21:02 | 0 Comments

One of the intermittent problems we face when developing with OI 10 is knowing about the new properties and features that we now have access to. The pace of development is so rapid that the documentation just doesn't keep up. There's a fine source of documentation at revDevX.com along with multiple blog posts at the same site but sometimes the Lord helps those who help themselves.

With this in mind, we'll use a real world example to illustrate how much easier life can be when we have access to such new features.

We recently wanted to have a radio button contract or expand based upon a control record. We knew how we would have accomplished this in the past - we'd grab the button control object, destroy it, modify it then recreate it. That's all well and good, it works and the control stays at the right place in the tab order - but it can change the Z-Order of the control which isn't always desirable.

Naturally we wondered if there was a better way in 10.

Of course there is, or we wouldn't be making this blog post.

Taking a simple example where we want to alter the available buttons based on the membership type, we'd have one set of radio buttons for the member type and another for the letter type.


An existing member wouldn't need a Welcome Letter so clicking on "Existing Member" has to do this



i.e. the "Welcome Letter" option is removed.

We all like to boast that OpenInsight is written in OpenInsight but the implications of this can be missed in the excitement of the new environment. We're so used to OI not exposing all of a control's properties that we lose track of the possibility that what we need may be staring us right in the face.

The simple fact is, that if something exists in the property panel in the form designer for a control, then it is an exposed property. So let's look at the property panel for a radio button.



and what do we see as the fourth property? Buttons. 

Clicking on the options button displays a dialog containing the text and values for the radio button :-



As we've telegraphed this far in advance you can probably guess what this means - radio buttons expose a BUTTONS property. It consists of two columns, both multivalued. The first is the label description and the second is the associated code.



So now, to accomplish the above goal all we have to do is manipulate this property. Here's a simple code snippet to do this :-


If you're not familiar with the syntax being used for getting and setting properties check out the blog post here.

We'd encourage you to take a look around the property panels to see what other goodies you can find!



By Sprezz | Tuesday, 7 June 2022 14:25 | 0 Comments

 We've been doing a lot of stress testing of LH at Sprezz Towers to help a client with speed issues on large tables. As part of that we've created some 60 million row tables to play with combinations and permutations of differing indexing setups.

In so doing, we came across a situation where the index sort would get to 80% and then just exit with an FS220 error. (FS_REL_NEED_REBUILD_ERR$). Now to be honest, this was confusing to us as there wasn't a relational index on the table. So speaking to the good folks at Rev, it was clarified that this was the wrong error but for fairly obvious reasons we were the first to notice. After discussing further with them we came to the conclusion that it must be related to disk space.

So began an increasingly frustrating attempt to free up disk space (why oh why did I format my USB sticks with FAT32 and its 4GB file size limit?). Subdirectories were zipped, old files deleted until - finally we had the 40GB or so free that we needed. 

We tried again - and again around the 80% mark the index rebuild just stopped. It didn't crash, it just stopped - having cleared out the %ALL.IDS% token in the ! file.

As V119 was suspected to be the culprit, we redirected the temporary sort file in the environment to the same disk as the data tables so that we could keep an eye on what happened. 


At 77% and the sortfile is growing



78% and still going



and then - boom


It seems that the largest sort file that can be created is 2GB and that attempts to exceed this will fail. Note that this applies to both IDX_SETS1 and 2. This is a limitation of a 32 bit OS rather than OpenInsight, so can not easily be addressed in version 9.x.

Now it should be pointed out that this is a particularly extreme situation, as the row ids in this large table are 5 part and quite long. With a more normal key structure than the long complex one we were using, it is unlikely that this limit would be breached without having hundreds of millions of rows in the table... but it does mean that if you need to rebuild such large indexes you need to undertake the task in OI 10.1 where the issue has been resolved. Note also that this doesn't affect day to day use of the indexed table, normal additions and deletions will still update the index - this issue only affects a rebuild.

As a side note - if you DO want to do this in 10.x there is a major caveat. Indexing has been rewritten for 10 and works in a different way than 9. This means that out of the box, OI 9 and OI 10 have different indexing routines and are not compatible. Fortunately Rev have provided a way to deal with this.

All that we need to do is edit or create a record in SYSENV called CFG_RTI_UPDATE_INDEX. Set line 1 to RTI_UPDATE_INDEX_90 then save it, exit OI and restart. This will force 10 to use 9 indexing logic. We've been working a lot with indexes on large tables in 10 and we'd recommend using this setting in any case if you're working with large data volumes. By large tables, we are talking tens of millions of rows.

For the avoidance of doubt - if you are sharing data between OI 9 and OI 10 you MUST do this or you will experience issues.
By apk | Wednesday, 4 August 2021 17:48 | 0 Comments

This will probably be obvious to most, but it's been a real thorn in my side since day one of OpenInsight, and by day one I mean alpha testing and writing bits of OI 2.0 back in my apk@revelation.com days.

I've always had trouble remembering which property is LIST and which property is ARRAY.  Every time I use these, I either get it wrong or just load HELP to check which one is column by row and which one is row by column.  Finally, with a little help from Captain C, I have a working mnemonic.

ARRAY == Across, because the data moves across the table.
LIST == Lines, because the data comes back line by line.

Finally, almost 28 years later, I can stop searching HELP daily.

By Sprezz | 10:14 | 0 Comments

 Over the years, we've had numerous queries as to what exactly clientsetup.exe does and why it has to be run on each and every machine that will be running OpenInsight. With the help of RTI stalwart Bryan Shumsky, we've put together this post to tell you all you need to know about client install.

Over the years, OpenInsight has evolved from a pretty much self contained environment, where you could just pick up an application folder, move it elsewhere and expect it to work, to an environment which requires increasing levels of workstation adaptation. Firstly the OIPI print engine required that an OCX be registered at the workstation before it could be used. Of course, the OCX could still reside on the server, so all that was required for the client was an OCX registration via REGSVR32.EXE. The same went for the AREV32/64 command window. Then the new scintilla editor.

But as more of OI began to be developed in external languages, (specifically .NET) the requirements became more onerous. Windows doesn't take too kindly to being asked to run .NET components over a network and to make it happen, various security overrides need to be put in place. These are beyond the capabilities of a run of the mill installation script, so the decision was taken to install the .NET components locally on the workstation and to register them there. At this point it's important to add that you MUST install these assemblies on the local machine not on a network drive,

For reference, it is worthwhile pointing out that whilst historically the client setup is run from the OINSIGHT subdirectory, it can actually be run from any location as long as the "Assemblies" and "Client Files" subdirectories exist (with contents) relative to the clientsetup.exe.

With Bryan's help we were able to put together this list of what actually happens during a client install. So with no more ado, here's what the program actually gets up to...

First things first. Check if the client setup has already been run at some stage on this workstation - so it's off to the local registry the program goes. This makes it easier for the program to suggest defaults for the new installation.

Next, just to be nice, the program sets up shortcuts to the documentation, website etc etc.

Then, checks if there are already existing .NET assemblies at the requested installation location. If there are, they are removed. This is to stop the installation process interjecting with annoying messages about pre-existence etc.

Penultimately it then copies the files from the aforementioned subdirectories (Assemblies, Client Files) to the specified location on the local machine.

It then finally registers and installs the OCXs and .NET assemblies at their new local location.

Of course, there are circumstances where the client install might not be needed - for example if your installation doesn't need to edit, print, or sort information. Paradoxically this does mean that if you're running the engine server on the network server, you must ensure you do the client install on that machine too!

Hopefully this information will help you in understanding your deployment issues, and a big shout out to Bryan for helping with this.

By Sprezz | Wednesday, 14 April 2021 17:52 | 4 Comments

Like many Revelation consultants, we have a number of clients who continue to use decades old software under new, more modern technologies - specifically AREV32/64. A technology that was meant to provide a transition path to a more modern UI is frequently just used as a way to continue taking advantage of the massive ROI provided by Revelation Software - in this case AREV.

But sometimes, things go wrong. And this week we were bitten by a particularly pernicious bug that we hadn't seen before.

The client reported that suddenly, blank documents were being emailed to their customers rather than the order confirmations that they were expecting. Investigation was relatively easy - isolate the section of the code that creates the files and test this. The section of code in question simply executed a PDISK to redirect printer output to a file, produced the report, then PDISK PRNed to cancel the redirection.

Upon testing, it failed to produce any output, despite reporting that the redirection was successful. Following Occam's Razor we tried to reproduce the issue by issuing a PDISK at TCL, performing a simple LIST report to disk, then doing a PDISK PRN. Surprisingly, no disk file was produced. 






But looking at the subdirectory no file was created.



So we reverted to an older version of the software and tried again - regretfully with the same result. It didn't matter how far back we went, the error persisted. At this point it became obvious that this was not the issue that the client was facing - all had been well until the last upgrade - but it WAS an issue that we were facing in our testing. But our software was a direct copy of their system, so what could it possibly be?

We tried calling SETPTR directly, we tried different filenames and different extensions but to no avail. So it was time to roll out the big guns and deploy PROCMON, the stunningly useful utility from SysInternals available from Process Monitor - Windows Sysinternals | Microsoft Docs. We reproduced the lack of output with PROCMON running and examined the captured output. We filtered the output on process OENGINE.EXE and path containing ZZZZ.txt and saw 6 entries as below :-


The first 4 were as expected, but the last two were strange to say the least. The spaces in our directory path had been replaced with underscores - and strangely, Windows could not find a path with that name.

This provided us with a working theory - so we copied the system to a subdirectory with no spaces in the name and repeated the experiment. This time we saw the results we expected - a file containing output :-


and the PROCMON trace showed no errors


So it would seem that PDISK has been engineered not to work with subdirectories containing spaces in the path. 

By Sprezz | Tuesday, 2 March 2021 12:42 | 0 Comments

 With more and more applications (in Europe at least) moving to UTF8 we got to thinking about the inherent limitations in case conversion for developers in OpenInsight. Historically developers have changed from lower to upper case by simply converting @lower.case to @upper.case in the string to be converted. This is all well and good in an ANSI system but could create issues in a UTF8 system.

The strings @lower.case and @upper.case aren't magic - they are just text strings loaded by the system at startup, and there is no way that they can easily be made to contain all of the characters necessary in a UTF8 system. Naturally we could manually load them with all of the characters that we think might be required but the strong chances are we'd miss something, and in any case it's 2021 - there has to be a better way right?

Right.

Of course there is - it's an issue all Windows developers face - not just Rev developers. So naturally Microsoft have made it easy by providing two exported DLL functions for developers to use, namely CharUpperW and CharLowerW. (For an explanation of why we are using the W version rather than the A see this blog entry). These functions do the conversion of the string "in place" - so we simply have to call them passing in the string to be converted and it will be changed in the string (rather than returning a changed value).

The only drawback is that to be able to use it, we have to prototype it first in a DLL definition. Historically this was a messy process, involving creating a DLL Prototype for the functions, saving it and then running a system routine called DECLARE_FCNS against this definition. If you're not familiar with this, where have you been for the last decade or so? ;). Then if we wanted to track the definition for deployment we'd have to create an APPROW definition because the OI Repository didn't know about the existence of DLL prototypes.

Fortunately in OI 10, DLL Prototypes are now part of the OI entity family and as such there are UI tools to accomplish all of the above. So let's see how we'd go about defining the above two functions.

Let's go to File/Entity/New


and select DLL prototype record. The DLL Prototype Designer launches and we can define our functions. Let's start by telling it that the functions we need are in USER32 and define a namespace (a unique string to prepend to the name of the function so that somebody else's (potentially incorrect prototype) definition doesn't overwrite ours). This particular function doesn't return a value  so we're going to use a return type of VOID :-


It's a STDCALL type (like most definitions we make)


and it takes an LPWSTR type



Then define the arguments for both functions


and apply the namespace (to which I've remembered to add an underscore :))


Then save it using Ctrl-S


The system obligingly tells us that is has saved the prototype


and finally we can compile the prototype (running DECLARE_FCNS effectively) by pressing F9


We can check that the system functions as in version 9 by checking for the DLL_ row in SYSPROCS


and sure enough - the only difference in 10 from 9 is that there are now comment lines for the namespace and comments :-


The routines are now available to us to perform UTF8 compliant lower and uppercase conversions. So "convert @lower.case to @upper.case in string" becomes "call zz_CharUpperW( string )" and "convert @upper.case to @lower.case in string" becomes "call zz_CharLowerW (string )". Of course there's nothing to stop you aliasing the functions to more friendly names like "toUpper" or "toLower" but there's always the chance of a clash with existing names. 


Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel