Associate your own file type with Windows Explorer

From LabVIEW Wiki
Jump to: navigation, search

Note about custom file type handing in LabVIEW 8.2 and up

In LabVIEW 8.2 an Application event called "OS Open Document" exists, which provides a LabVIEW native way to handle custom file types.

LabVIEW 2009 and 2012 have this event working as well. Other versions needs further testing.

Here is a snippet of code in LabVIEW 2009 that works:

OpenDocumentEvent.png


See this LAVA posting for information.


Guidelines to open your own file type from Windows Explorer

When the user double-clicks on a document, the Registration Database is checked for an entry that associates the file extension with a particular application. If an entry does not specify Dynamic Data Exchange (DDE) command, the application specified in the registry is launched. If the registry specifies to use DDE commands, an attemp is made to establish a DDE communication with that application using the application topic. If an application responds to the DDE connection, a DDE Execute command is sent to the application, as specified in the registry. However, if attempts to establish the DDE conversation fail, the specified application is launched and the DDE connection is tried again.

File associations and LabVIEW

LabVIEW registers the file extensions *.vi, *.vit, *.ctl, *.ctt and *.llb in order to open these files when the user double-clicks on them. A LabVIEW standalone application registers file extensions *.vi and *.llb when its configuration file (.ini) contains the line RegisterExtensions? = True. However this allows LabVIEW to open its own files and does not provide a mechanism for your application to open its custom files using registered extensions.

For example, your application reads and writes custom data files to which you consistently give the extension ".myx". One thing you can do is to associate the file extension (no DDE command) to your application. When your application is not running, double-clicking on a .myx file launches your application and you can make a system call to read the command line from which you extract the file name to act upon. Remember that, whatever its extension, LabVIEW first tries to open the command line file to figure out if it is a LabVIEW file that it can open (VI, control or LLB).

Once your application is running, double-clicks on your custom file starts a second instance of your application. This instance detects that there is already an instance running so it sends the command line information to the first instance through a DDE Execute command and terminates. The first instance receives the command line; if there is no VI or LLB paths to open, the command is discarded. Currently, there is no way to recover this command line because you have no access to the application built-in DDE Server. Therefore user double-clicks have no effects when your application is running.

In order to receive DDE Execute commands, you would have to, after having properly registered DDE commands in the registry, implement in your application a DDE Server that responds to the DDE Execute commands sent by the system. Unfortunately, altough LabVIEW DDE Client palette offers a DDE Execute.vi that can be used to send commands to other application to open files, the DDE Execute server function is not supported. Such a function would allow to receive the commands sent from the system on user double-clicks (or other applications DDE clients).

DDE being a legacy from Windows 16 bits OS, it is a fading out inter-application communication mechanism. In the latest version of LabVIEW, DDE VIs are still supported but have disappeared from the default palette. Therefore it is very unlikely that DDE VIs will ever be enhanced to support DDE Execute function. One could write a DLL that fully supports DDE, but given the obsolescence of the mechanism, it would be a waste of time.

There are alternatives that we can use to emulate in part the file opening from the file system. The workaround to DDE is to have another executable intercept the command line each time your files are double-clicked on, transmit it to your application and terminate. I will describe three ways below but first let's see how you can register custom file extensions.

Register a File Extension

You register file extensions in Windows Registration Database running the regedit.exe application with a text file that contains the keys and values to register. For example, if you want to open .myx extensions with the application myx.exe (or myx.bat or other executable files) located in c:\myx directory, you create the file myx.reg with the following lines:

[code]

REGEDIT
HKEY_CLASSES_ROOT\.myx = myxfile
HKEY_CLASSES_ROOT\myxfile = My Custom Data File
HKEY_CLASSES_ROOT\myxfile\shell\open\command = c:\myx\myx.exe "%1"

[/code]

You register the file association from your application using System Exec.vi with the input string

[code]"regedit.exe /s c:\myx\myx.reg"[/code]

Alternatively to the use of regedit.exe, LabVIEW 6 is now distributed with VIs to edit the registry. Registry edition VIs for previous versions of LabVIEW are also available at http://www.mhst.de/support.html, more specifically here: Windows 95/NT Registry VIs.

Associate the extension to a DOS batch file.

A simple way is to associate your file extension to a DOS batch file that writes the command line argument to a text file. The file myx.bat contains the following lines:

[code]

ECHO %1 > c:\myx\myx.txt
START c:\myx\myx.vi

[/code]

On file double-click, the batch file executes. The first line of the batch file writes the DOS 8.3 file path/name to the file myx.txt (previous file content is overwritten). The second line starts the VI myx.vi. Provided that your application is currently associated to .vi extension (RegisterExtensions = True in its ini file), your application will load myx.vi. The VI myx.vi (set to run when opened) should read the myx.txt file to extract the name of the file to open. If your application is already running, it can now be notified by myx.vi that a file has been double-clicked in the file system. If your application was not running, only myx.vi will be loaded and run; the application Top Level VIs are not loaded therefore myx.vi should check for your main Top Level VIs and load/run them if necessary to properly launch your application. The batch files terminates immediately after the start command and is ready for the next double-click. It is preferable to set the batch file properties to run minimized and close when finished. The long Windows path of the file can be obtained with the VI "GetLongPathName?.vi" included in the sample code below.

You will agree that sending a file name to your application using a DOS batch file and a text file for data tranfer is not state-of-the-art programming, using techniques older than DDE itself. The following methods use the same principle but allows to send the file name to your application using ActiveX, VI Server or TCP/IP.

Create your LVShellOpen.exe executable.

Instead of a batch file, one can use a small LabVIEW executable (let's say LVShellOpen.exe) to be associated with your file extension. Normally, when a LabVIEW executable is launched with a file path on the command line, it attempts to open the file to check if it is a LabVIEW file (VI) it can execute. To prevent this and speed up the process a little, the registry command can be modified to included a command line switch such as

[code]HKEY_CLASSES_ROOT\myxfile\shell\open\command = c:\myx\LVShellOpen.exe - o"%1"[/code]

Since the executable does not recognize a file path or a known switch on the command line, it ignores it. This has also the advantage that if you want to implement other file system commands LVShellOpen can distinguish them if different switches are used. For example, a second command Print could be registered as

[code]HKEY_CLASSES_ROOT\myxfile\shell\print\command = c:\myx\LVShellOpen.exe -p"%1"[/code]

When lauched after a double-click, LVShellOpen launches your application if it is not already running, sends the (Windows Long) file path to open and quits immediatly, ready for the next double-click.

The mode of communication to transmit the file path from LVShellOpen to your application is up to your choice. VI Server or TCP/IP are good options (why not DDE?). When LVShellOpen awakes after a double-click, it attemps to establish a connection with your application (you have enabled the VI Server or run a TCP/IP Listener). If connection succeeds, the file path read from the command line is sent to your application. The connection is closed and LVShellOpen exits. If the connection fails, your application is launched using a System Exec.vi call. LVShellOpen can include the file path on the command line and let the application open the file from its command line or alternatively it can wait for the activation of the VI Server or the TCP/IP Listener to transmit the file path before exiting.

Visual Basic Script* and LabVIEW ActiveX Server.

LabVIEW and executables created with the Application Builder have a built-in ActiveX VI Server. By default, the ActiveX server is not enable in the application builder settings. On the "App Settings" tab of the Application Builder, check the box "Enable ActiveX server" and give an appropriate name to your application server.

It is possible with a simple Visual Basic Script (vbscript) to call LabVIEW VIs using the ActiveX VI Server. Making the file association to the vbscript, this one can easily call one of your VIs to transmit the file path on double-clicks from the user. Opening a connection to ActiveX VI Server automatically starts your application (running Top Level VIs) if it is not already running. The script then makes a call to a VI (included as dynamic VI) that fills a front panel string of the VI with the file path.

This technique does not require to build a separate application and thus can be used with all LabVIEW releases. By making the whole code reentrant it is possible for the user to select multiple files and to open them simultaneously.

This is the technique I recommend the most.

Download Sample Code for VBScript and ActiveX.

"*To run a vbscript, you do not need Visual Basic but the Windows Script Host component which is included in all but the oldest versions of Windows and Internet Explorer."

Conclusion

In conclusion it is possible with some workarounds to manage custom file extensions in a LabVIEW application. However, a built-in LabVIEW feature to implement such interaction with Windows is, to my opinion, highly desirable. If you feel the same way, please add weight to my request for this feature on the LabVIEW Wish List and fill out the LabVIEW Feedback Form