donderdag 30 mei 2013

Launch clientside executables from webapplication

Some time ago I wrote a post "A method to execute external programs via APEX", here DBMS_SCHEDULER was used to execute commands on the (database)server. Recently we had to find a way to "launch clientside executables via APEX". On the web various solutions are described using ActiveX (via shell.application), but for some reason I wasn't able to get that running. To be clear about our ambition: we want to launch a program, add some parameters, on the clientmachine that is viewing our webpage. We thus want to leave the browser sandbox. The path we took was inspired by the following hyperlink. In a nutshell; we add an URI handler to the Windows registry so that hyperlinks of the form
  Myhyperlinktext 
launch the windows notepad program on the client with argument <<text>>. Adding an URI handler requires us to make a modification to the windows registry: we need to tell Windows that hyperlinks of the form "webrep:<<text>>" launch notepad with argument <<text>>.

The before mentioned hyperlink uses Inno Setup, to build an installation program that makes the registry modifications for us. The beauty of Inno Setup is that de-installation of our registry modification is very easy (via default add/remove). I left the default setting pretty standard and added the following lines to the new setup file:
; Script generated by the Inno Setup Script Wizard.
[Files]
Source: "files\launch.cmd"; DestDir: "{app}"
Source: "files\demo.html"; DestDir: "{app}"

[Registry]
Root: HKCR; Subkey: webrep; ValueName: URL Protocol; ValueType: string; Flags: uninsdeletekey
Root: HKCR; Subkey: webrep; ValueType: string; ValueData: URL:webrep Protocol;  Flags: uninsdeletekey
Root: HKCR; Subkey: webrep\DefaultIcon; ValueType: string; ValueData: {app}\launch.cmd,0; Flags: uninsdeletekey
Root: HKCR; Subkey: webrep\shell\open\command; ValueType: string; ValueData: "{app}\launch.cmd %1"; Flags: uninsdeletekey
After compilation of the setup file, Inno Setup gives us setup.exe. This executable does 2 thing. It copies the required files (that are included in the installer) to a setup-user-defined directory and makes the required modifications to the registry. The contents of launch.cmd are as follow:
@ECHO OFF
set parameter=%1
ECHO.
ECHO Don't close this window.
ECHO it will close automatically when notepad is closed.
ECHO.

cmd /c "c:\Windows\System32\notepad.exe %parameter:~7%"
The contents of demo.html are as follow:
<html>
	<head>
		<title>D E M O</title>
	</head>
	<body>
		<a href="webrep:mynewfile.txt">Click me!</a>
	</body>
</html>
Clicking the hyperlink will cause notepad to lauch with a mynewfile.txt. Making this work in APEX is quite straightforward.