LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Does "Recursive File Search" and/or "Check if file or folder exists" work on the contents of an executable?

Solved!
Go to solution

I have an application that dynamically loads child classes at run time. I don't explicitly call these classes on any block diagram, and therefore I have to call them by path if they're not in memory of the executable. They are included as "always include" in the build. This causes UI jitter (calling that way uses the root loop). As a solution, I wanted to search the folder where they all reside within the folder structure of the executable and load them all at startup (get the jitter out of the way early).

 

I've already convinced myself that the pathing is correct. However, it gives an error 7 when I try to call "Recursive File Search" on the folder that contains all these classes. Works just fine in development, but in the executable, I get error 7.

 

All that to ask, are these calls valid for searching within the file structure of an executable? I suspect they may not be. If not, how could I accomplish the same thing?

0 Kudos
Message 1 of 4
(1,518 Views)
Solution
Accepted by topic author thutch79

Unfortunately, NI disabled the ability to list the contents of executables after some users felt that that was a major security concern in terms of reverse engineering their precious IP. So the List Folder node simply returns an error when given a path to an executable or inside an executable.

 

You will have to structure your classes in a specific way on disk and then use relative paths to a VI you use as reference. Inside that VI you use the This VI Path constant and strip one level from this.Then you append the relative path to where your VI is located in respect to this directory and use that path to open the VI reference or class. When you build the executable LabVIEW maintains the relative filer hierarchy inside the executable and your paths still work.

Rolf Kalbermatter
My Blog
Message 2 of 4
(1,505 Views)

I suspected it was something like that. Thanks for confirming.

 

The reason I wanted to go this way was we often add to the list of child classes. I'd rather not have a task of making sure either there's a object constant on a diagram for each one, or I maintain a list of them somewhere to load. I think I'll go with a pre-build action to generate an array of strings.

 

Thanks for your help.

0 Kudos
Message 3 of 4
(1,447 Views)

Another way is to use a factory pattern type.

 

You arrange the directory structure in a way like this:

 

Type1/Type1_Base.lvclass

Type1/Type1_Imp1.lvclass

Type1/Type1_Imp2.lvclass

 

Type2/Type2_Base.lvclass

Type2/Type2_Imp1.lvclass

Type2/Type2_Imp2.lvclass

 

All classes implement a dynamic dispatch Constructor method (and Destructor)

The Base class implements an Init (Create, Genesis, or whatever) method which accepts a string that indicates which implementation you want to create. In there determine your current path, move up to the TypeX common directory, append the specific implementation class name, and do a Get LV Class Default Value.vi call on this path, upcast the returned generic object to your base class and call the Constructor method, et voila. 

 

Now you always call the Init.vi for your base class with a simple string that indicates the desired specific implementation. If you end up needing anything else than the base class at any point, it's usually a good indication that your problem is not something that should be solved with inheritance but rather with composition. There are a few possible exceptions to that, but they are few and far in between.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 4
(1,439 Views)