The Best Laid Schemes
Recently a client asked us if there was a way to call OpenInsight externally using a URL syntax. Initially we were confused because this client was already using the OECGI to enable HTTP access (i.e., via a URL syntax) into his application. After a few more email exchanges we came to understand that the client was interested in creating a custom URI Scheme for OpenInsight like so:
The goal of this endeavor would be to create a URI (i.e., a linkable resource) that would automatically launch the OpenInsight application and then perform some specific action based on the path of the URI. In the above example, OpenInsight would perhaps automatically open Invoice #12345 in the designated form.
In the Grand Scheme…
So what exactly is a scheme and why would someone want to call an OpenInsight application this way? The what question is easy to answer. A scheme is what defines how a URI syntax should be handled. We use standard schemes such as http, ftp, or perhaps even mailto on a daily basis. While schemes should be registered with the IANA, non-registered schemes are commonplace.
The why question is a bit more subjective. Commercial applications, such as iTunes, Spotify, Slack, and Citrix, use custom URI Schemes for various reasons. In general, they are often used to launch apps without requiring a password (because the link is emailed to the registered user) or to call up resources within the app (such as a song within the library). In our client’s case, he wants to send colleagues a link via Slack so they can quickly open a record within their in-house OpenInsight application without having to go through the normal manual steps.
Registering the Scheme
Obviously, any operating system must be configured to identify a URI Scheme and know how to process it. Different systems have their own methods, but we only need to worry about Microsoft Windows. Fortunately, this is a rather straight-forward process which is documented in this short Microsoft document. If you prefer to not read this article, all you really need to know is that custom URI Schemes are defined by adding a key to HKEY_CLASSES_ROOT along with associated sub-keys. The structure is rather uniform and simple. Here is an example of what an entry might look like:
HKEY_CLASSES_ROOT myapp (Default) = "" URL Protocol = "" DefaultIcon (Default) = "MyApp.exe,1" shell open command (Default) = "C:\MyApp\MyApp.exe" "%1"
In fact, the above entry can be downloaded using this link. Simply edit the MyApp.reg file using your favorite text editor and swap out “MyApp” with your own application name and change the path to where your application lives. Then you can merge the file into your local Registry. Once this is done, you can test your scheme by entering myapp: (or whatever you called it) in any web browser or via the Windows Run command line (WinKey+R).
…Oft Go Astray
There is a bit of a wrinkle in our plan to create a custom URI Scheme for OpenInsight. Whenever we attempt to launch OpenInsight (OINSIGHT.exe for 32-bit or OpenInsight.exe for 64-bit) without the aid of a shortcut or without already being in the application folder, we encounter errors due to the Start In directory not being properly set. For example, when attempting to launch OINSIGHT.exe via a URI Scheme we see this dialog:
Unfortunately, the URI Scheme Registry command value must point to a .EXE file. Otherwise, a .BAT file might come in handy. Therefore, an alternative method for launching OpenInsight without directly calling OpenInsight must be utilized. There are various solutions that developers are using, but we’ll shamelessly plug our own tool: The SRP Application Launcher. The SRP Application Launcher provides developers an easy way to create a custom .EXE file to launch OpenInsight without exposing command line parameters.
Speaking of command line parameters, they are another reason why calling OpenInsight directly is problematic (at least for the 32-bit product). Since the URI Scheme would call OINSIGHT.exe bereft of the special parameters, the OINSIGHT.INI file would be used to provide the default application and user name (assuming it has already been updated). This means there is no guarantee that OpenInsight will launch as intended.
Handling the Scheme
For demonstration purposes, we created MyApp.exe using the SRP Application Launcher and then created a corresponding MyApp.ini. Once we did this, entering myapp: from our browser’s address bar automatically launched OpenInsight. Woot! But what if we entered something like myapp://invoice=12345? How would we get this information and use it? The answer to this question relies on the understanding that whenever a URI Scheme is used to launch a Window’s application, the ShellExecute API is used. Hence, whatever is entered after the colon (i.e., the path) in the URI Scheme is appended as a command line argument. This means we can retrieve this using the GetCommandLine API function. Fortunately, this API function is already defined in newer versions of OpenInsight so you just need to declare it and call it like so:
Declare function GetCommandLine Command = GetCommandLine()
The most natural location for this code would be in the CREATE event handler of your application’s Entry Point form. You’ll see something similar to this:
At this point it is a simple matter of parsing the string and calling the appropriate code to perform the desired behavior.
The SRP Launcher ActiveX Control
Since we are using the SRP Application Launcher in this illustration, we might as well point out another feature that nicely compliments standard URI Scheme functionality. As you may have experienced already with other URI Schemes, when the target of a URI Scheme is already running, calling the URI Scheme again typically does not launch another instance of the application. Instead, it usually brings that application forward onto the desktop and then switches a mode to reflect the path passed in with the URI. In our example above, if OpenInsight was already running, instead of launching another instance of OpenInsight, the expectation would be that the currently running instance would be invoked and notified of a new path (i.e., invoice=12345), requiring some action to take place.
Enter the SRP Launcher ActiveX control. By itself this control does nothing, but when it is running on an application form (presumably one that is always running, like the primary MDI Frame), the SRP Application Launcher will call its OnLaunchAttempt event handler instead and pass in the new command line argument:
As with the CREATE event handler, the same code can be called to perform the desired action.
There are other details that still need to be sorted out. For instance, a method for updating the Registry for all desktop clients must be created. This is easily done through a custom software installer, through group policy administration, or even by OpenInsight itself using a Registry API (like the SRP_Registry function). Integrating your URI Scheme with third-party tools, like Slack, will also require some tooling but this isn’t difficult. Finally, whenever a URI Scheme is used to interact with a Windows application, the end user is prompted to give it permission, although these permission dialogs usually include a checkbox to always allow permission.
Does this article spark any interest in custom URI Schemes for your OpenInsight application? We would love to hear ways in which you think this kind of integration might be useful.