From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

VI to determine Project name

Solved!
Go to solution

For a Real-Time application, I wanted to determine, at run-time, the name of the Project in which the VI was "contained".  I wanted to get the (same) Project name under four separate conditions:

  • on the Host, in Development mode
  • on the Host, in Run-Time mode (i.e. after being built as an Executable)
  • on the RT Target, in Development mode
  • on the RT Target, in Run-Time mode.

It's not so easy.  I figured out how to do the first two (use the Active Project's Name property in Development mode, and use the next-to-last folder of the Application Directory in Run-Time mode), but I'm having difficulty getting this information for the RT Target code.  Has anyone tried  doing this?  Were you successful?  Hints (or even outright Solutions)?

 

Bob Schor

0 Kudos
Message 1 of 5
(3,101 Views)

The question here is why do you need this, and maybe we can propose another way. You could create a custom pre-build step and put a string constant in your diagram. You can then write to that string constant the name of the project and resave the VI using scripting in that prebuild step.

0 Kudos
Message 2 of 5
(3,079 Views)

Why do I want to do this?  Well, I'm looking for an Elegant "Solution" to the following situation:

 

We have several (3 to 6) fairly complex RT systems that run behavioral experiments, collecting analog and digital data from multiple channels, delivering various stimuli at precise time intervals (and at precise spatial coordinates), streaming all of the data to disk for later analysis while providing real-time views of the data, all driven by an Excel Workbook whose rows indicate the sequential sequence of trials we wish to undertake.

 

It is extremely important that we "match" the Host UI code with its corresponding RT Target.  In the "Good Old Days" of LabVIEW 7.0, we accomplished this by placing named LLBs (with names corresponding to each of the UI "Masters") on the RT Target, and then "invoking" the appropriate RT code using VI Server calls.  Now, however, we are embedding each system in its own LabVIEW Project, with a UI and an RT section, and want to develop and deploy pairs of Executables.

 

It occurred to me that, whatever the name of the Executable (which can be almost arbitrarily named in the Build process), the one common identifier that binds the UI and RT code is that they are in the same Project.  Suppose I want to have each of my various routines use a Configuration file.  If I name the file <Project> Configuration.xml (where "<Project>" is the name of the Project), and, if at Run Time my UI and RT routines could determine with which Project they are associated, I could write one routine that would automatically go to the appropriate Config file for the data.

 

I have figured out how to do this for the Host UI code, both when run in Development mode and as an Executable.  I'm having less success in doing the same with the RT side.  That's why I would like to do this, to have an elegant, consistant, idiot-proof method for the UI Host and RT Target codes to agree on a logical process for creating files, folders, etc. and for sharing data.

 

Bob Schor

0 Kudos
Message 3 of 5
(3,051 Views)
Solution
Accepted by topic author Bob_Schor

Well, I figured it out, but it isn't pretty.  In the previous post, I explained why I wanted to do this -- here I'll explain how I did this.

 

There are three main modes under which Applications can run:  Development mode (when you are programming in LabVIEW and hit the "Run" button), Run Time System (an Executable on a PC), and Embedded (code running on a Real-Time Target, whether in Development or Executable form).  Of these, only Development mode gives you direct access (via the Application, Active Project property) to the name of the Project file.  Since my goal is to have both the UI and RT "pieces" of the Real-Time Project have access to the Project Name, the system I'll build will use identical code on both sub-systems, meaning it will be run on the PC at least once in Development mode.

 

The key step is to create a "Constant VI", which I'll call CONST Project Name, that consists of a single String indicator, Project Name, that will "hold" the Project Name.  I originally thought of using a Global Variable, but there's a technical problem with this I'll mention later.  I won't use CONST Project Name directly, but will, instead, use a VI "Get Project Name" that has, as its sole output, the Project Name.

 

This VI, when it executes, determines the Application Kind under which it executes.  If it is anything other than Development Mode, it calls CONST Project Name and returns its value.  If it is Development Mode, it gets the Project Name, returns it, but just before exiting, it arranges to programmatically update CONST Project Name so when the latter is called in the future, it will return the (updated) Project Name.  [So why not simply initialize CONST Project Name?  I'm looking for a "generic solution" that will always return the right value, even if I move it into another Project and don't remember about editing and changing it -- all I need to do to make it work is to run it once in Development mode.  Who ever develops code without testing it before making the Executable?].

 

I wrote a VI called Save Project Name that does the following -- it invokes Set Control on CONST Project Name to set the new Project Name (this works even though we are setting an Indicator), invokes Make Current Default to make the new value "stick", and invokes "Save Instrument" to save the changes.  The catch is that CONST Project Name cannot be in the "Running" state for Make Current Default to work without throwing an error.  If Save Project Name is simply called as a sub-VI from Get Project Name, it will be in the Running state as it is used in the non-Development mode cases in Get Project Name.  The solution to this Gotcha is to use Asynchonous Call-and-Forget to "spawn" Save Project Name.  Finally, we modify Save Project Name so that it starts with a "Wait Loop", examinging the Execution State of CONST Project Name and waiting for it to exit the Running state, indicating it is safe to proceed with modifying it.

 

Whew!  But it works!  Curiously, when I first tried this using a Global Variable instead of my Constant VI, I kept getting errors when executing Make Current Default, but despite the errors, the code seemed to execute properly.  I found an article (written for LabVIEW 5!) explaining this was Expected Behavior as Globals were always in the Running state.  Actually, I just realized that I hadn't tried this with the Asynchronous Call-and-Forget scheme, so maybe a decade later, LabVIEW will let me do this using a Global without throwing an error ...

 

BS

0 Kudos
Message 4 of 5
(3,013 Views)

Why don't you use scripting and make it a prebuild step like I suggested, setting the indicator to the project name before the build is done and then saving the VI? This way the code never has to be run in the development environment, and there is no don't-forget-to-do-this step if another programmer takes over.

Message 5 of 5
(3,002 Views)