Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: Sep 6, 2006


Feedback


Yes No

Related Categories

Related Links - Developer Zone

Related Links - Products and Services

Deploying Applications Using a Loader

10 ratings | 3.60 out of 5
Print

Overview

When deploying larger applications, you often want to structure your built application, so it runs exactly like your development build, which allows you to easily incorporate updates and archive both the built application and source code in the most efficient manner possible. Using a loader, I can satisfy these requirements.

Introduction

When deploying larger applications, you often want to structure your built application, so it runs exactly like your development build. Thisallows you to easily incorporate updates and archive both the built application and source code in the most efficient manner possible. I have found that by using a "loader," I can satisfy these requirements.

Background


In the early stages of a rather large project a couple of years ago, I discovered a difference in behavior of the application between the LabVIEW development environment and the built executable. While this issue was later resolved, the need for immediate solution led to a tidy solution that I never changed, despite the correction of the original problem.

I solved the problem by building a simple executable that loaded my main virtual instrument (VI) and built this as the application. It was quite simple to build and worked flawlessly. The built file was a simple loader, a VI that loads another using the VI server. It required only a couple of calls to the VI server to load before running the target VI. Thus, creation, testing, and build took a few minutes and never had to be done again.

This solved the initial problem of the performance difference between development and runtime environments. It also created an ideal situation for this project. Because the loader was the only built application, the VI hierarchy was left intact, in its project development form. This allowed me to archive the project completely. The source code and executable were all in the same directory structure. This also allowed not only for easier development of the project, but also meant easy completion of that updates. This provided increased productivity. More time was spent in development without spending time ensuring I completed the build properly. This was of tremendous importance to a project that began behind schedule.

Creating the Loader


A loader is a simple VI that uses VI server to call the front panel of a target VI, and runs the VI. The image below is a screenshot of the diagram of the loader application.



The loader first opens a reference to the main or target VI, in this case "MyProgram.vi". The VI Server then opens the front panel and runs the VI. Next, the loader closes the reference to "MyProgram.vi" and exits. The error handler informs the user of any errors. Because most errors that would occur are missing VIs, it is best to avoid custom error handlers. Custom error handlers are not recommended as the most likely error that would occur is missing VIs, which would likely include the custom error handler. Once complete and tested, the loader is built as an executable with the runtime engine as a separate DLL, which must be installed on the target machine.

That summarizes the functions of the loader. If you want to add other features, you can. The loader lends itself well to a splash screen. If you create the front panel of the loader to the standard size of a Splash Screen (400X300 pixels) and drop in a bitmap image, you can create a professional looking splash screen. You must add adequate delays and other features, such as loading displays and other niceties.

In addition, you can customize the loader to store any dynamic VI into memory and call other initialization functions while the application is loading. This option provides enormous provides enormous flexibility.

Prerequisites


In order to take the fullest advantage of this method, and to make it much easier on you during development and deployment, it is best to work in a deployment directory structure. This is a directory hierarchy created during development, which replicates application deployment. Because LabVIEW is quite good with relative directories, you can place your directory hierarchy anywhere on your system. For example, you may want to place them in a folder or a root directory called "projects". The project folder (\Projects\Project_Name) becomes the deployment root directory. From there, it is a simple matter of building the directory structure. There are many ways to create a directory structure, and each will vary in usefulness. While others may make recommendations on basic structures, you must plan your own directory structure. Suffice it to say that it is always better to overdo it than to not create enough folders. You can always delete unnecessary folders when you deploy the application.

A typical hierarchy can look like this:

\Projects
>\Project_Name
>ProgramLoader.exe
>ProgramLoader.ini
>>\Code
>>Program.vi
>>Program.ini
>>>\Support
>>>ThisVIsPath.vi *
>>>ConfigData.ini *
>>>\Tests
>>>>\Test Subs
>>>>\Test Config Data
>>>\Controls
>>>\Data
>>\Reports


ยท More about these later


The hierarchy creates an organized place to categorize appropriate files for your project. It is very wise to duplicate support files and core functions from the normal database into this project folder, as you will need them in the deployment. You want to be able to control the version of the core functions to avoid disrupting your application if you must change the version. You can easily locate files by placing them in a logical place within the files once you create a logically organized hierarchy.

It is important to note that in this type of hierarchy deployment scheme there will be some instances where you will need relative path information. This provides a standard method for locating the path of certain objects. For example, you can create a marker VI, which simply outputs its stripped, directory only path. This marker VI stores in a specific place within the directory structure. In this same directory, you can place any important files, such as configuration files or dynamic VIs. In the hierarchy illustrated above, the marker is "ThisVIsPath.vi". You can read from and write to a configuration file called "ConfigData.ini". Rather than memorize the exact path of the ini file, you can use the output of the marker as the location of the file. It is important to note there is a major difference in the output of this marker between a development copy, and when it is within a built application or DLL. The marker will output the correct path in development and if it remains a VI after deployment. However, if this marker is put into an executable or DLL, it will instead output the path of the executable or DLL, so any files being marked must be moved (duplication is preferred) to the same directory as the executable or DLL. While this sounds troublesome, it can be a big time saver. You should make this a standard procedure when creating applications, since you never really know how you will deploy the application.

Advantages and Disadvantages - When to Use or Not Use this MethodAdvantages and Disadvantages


There are definite instances when a loader is not the preferred method of deployment for LabVIEW projects.

First, if an application must be 100 percent secure and protected, and you need to keep the components of the application confidential, then using a loader is a bad idea. However, you must evaluate this need, as there are definite decreases in productivity in using a loader. If a target application must be a single executable with only support files optional, and you can afford the productivity hit, then a loader is not the right answer. However, you can use a loader during development if needed to test deployment.

The presence of the original code is a disadvantage of a loader when deploying an application. With the original code left as unlocked VIs with diagrams present, a user could alter names, or delete files. Worse, a user could install LabVIEW on the target system or duplicate files to a development system, and modify them, possibly corrupting the software. Of course, you can implement security to minimize or eliminate this risk. System and hardware failures, such as hard disk failure, or file corruption, can always occur, so using a loader in these situations will neither help nor hurt you. Just because you have more files does not mean you are more at risk. You can not protect against these failures. However, removing diagrams or password protecting VIs provide a great measure for protection. In addition to password protection offered by LabVIEW, making files read-only and archived are great system-based means of protecting your files.

Another disadvantage is that loaders do not lend themselves well to DLLs. By nature, DLLs are typically a single executable and therefore, would not work well with a loader.

There are also a great number of advantages to using a loader, in addition to the primary outlined above. Of course, productivity is probably the greatest advantage. It takes a great deal of time to build an application correctly. Practice does make perfect, but constantly rebuilding the application to learn how to build it quickly is a detriment to productivity no matter how you view it. You can create a standard loader template with an organization that requires only minor changes, such as name, target, or splash graphic for other projects in the organization.

The ability to scale and upgrade the application is a very big advantage of a loader. First, you can scale the application to any degree by merely adding files to the hierarchy. Of course, you must recompile the code, but the loader does not have to be rebuilt. Without a loader, you must update the build file with these new files when you add any VIs to the project. When you modify VIs after deployment, you can drop them directly into the directory hierarchy without a name change or having to rebuild the loader application. Only the modified VI requires shipping if these updates occur after the application is in the field. Without a loader, you must rebuild the application. Otherwise, you must ensure all required are used dynamically. This could result in extensive use of the VI server to call these dynamic files.

With the loader, you can also use a third party installer to deploy the application very easily. Alternatively, an installer does not even need to be used. You can simply copy the files to the target system. You can write a batch file to simply copy the source folder to the target machine. Or, write a LabVIEW program to handle the job. For the project in question, you can use a written procedure to have the end user duplicate the contents of the Source CD to the Target machine. Of course, since the LabVIEW 6.02 Application Builder did not provide a means of copying a directory hierarchy, the inability to use the Application Builder’s Installer option was a disadvantage in this case.

Archiving provides another advantage. An extra copy of the deployment CD was made and archived. There was not a single minute spent doing this. As the Deployment CD contained all of the final project VIs, there was no need to archive additional software and files from the development system.

Conclusion


Since the conclusion of the project where I discovered the loader method, I have used this method almost exclusively. In only one case did I not use a loader, and that was where a customer required a DLL. As the DLL was easy to manage, and function prototypes were necessary anyway, the process for the creation of built executables was unavoidable, and went fairly smoothly.

I am a regular contributor to the Developer Exchange. In recent weeks, I have recommended this loader method to many people. I decided to write this article after continued description of the loader method to others.

10 ratings | 3.60 out of 5
Print

Reader Comments | Submit a comment »

Good idea, yet poor explanation.
In general, while the article takes much effort to promotes/explain the use of a rather primitive function (ie vi server)in LabVIEW, it does highlight a good use for it. Unfortunately I did not find the style of the article all that appealing. While tending to fragment the sub topics (lacking flow - making it confusing to read), the author also tended to make bold claims without justifying them. Two examples: "First, if an application must be 100 percent secure and protected, and you need to keep the components of the application confidential, then using a loader is a bad idea." this statement wasn't justified, and I can't see any truth behind this statement. a second example: "Another disadvantage is that loaders do not lend themselves well to DLLs. By nature, DLLs are typically a single executable and therefore, would not work well with a loader." This statement would put off anyone wanting to use DLLs with served apps. I have been using DLLs with served vi's and executables for nearly two years now and while initially confronting a hurdle related to LabVIEW not finding the DLL, I have now have found them quite easy to integrate while using the 'loader' (AKA served vi) method.
- Oct 31, 2002

Dynamic VI loader
Good solution, but I use "Call by Reference node" instead. Usualy, I develop tests, that consist from number of submodules, each one is a small test. That is practical to loop all test's module's pathes, than define one connection plane for all of them, and call this tests by names, but one conn.plane. So, whole "dynamic loader" consist of (by stream) Initialization, Extraction off all path names from config file, Open_VI_Reference, Call_by_Reference_node, getting data (if needed, f.ex. for logging), Close_VI_Reference, (Logging..), looping back to Open_VI_Reference with the next vi PathName. This works fine, I think, and gives enough flexibility to deside sequence, develop new submodules without going back to "Old code". If You need example, or You does not understand my English, here is my e- mail: alexei.bluvshtein@delaval.com
- Alexei Bluvshtein, DeLaval Int. AB. alexei.bluvshtein@delaval.com - Oct 15, 2002

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).