Think for a minute about how paths work. A path is exactly where on the file system a given file exists.
The most versatile way to specify a path is relative to the VI that needs it (using THIS VI'S PATH). This allows you to move the VI or app and the directories that go with it as a whole, and the thing will still work.
If you're doing that, you need to understand what THIS VI'S PATH returns. It returns the full path to the VI that called it. There are three possibilities:
1... SomeDisk:SomeFolder:SomeVI <--- This is returned if called from a stand-alone VI file.
2... SomeDisk:SomeFolder:SomeLLB:SomeVI <--- This is returned if called from a VI within a library (LLB) file.
3... SomeDisk:SomeFolder:SomeApp:SomeVI <--- This is returned if called from a VI within an app (executable) file.
Notice that for stand-alone VIs, you strip path ONCE to get the enclosing folder (SomeDisk:SomeFolder).
But for LLBs or APPs, you strip path TWICE to get the enclosing folder (SomeDisk:SomeFolder).
For this reason, I have adopted the policy to never use stand-alone VI files. I always use files in libraries. Then the code doesn't have to change.
HINT: At startup, I find the root folder with the THIS VI'S PATH function, stripping appropriately. As part of this, I search for ".llb" in the container's name, and remember whether I found it or not. Whn the user chooses QUIT, I use the EXIT LABVIEW function, with the inverse of the FOUND IN LIBRARY flag, I set on startup. That means that the APP will completely close, not leaving a window around, but if you're in the LabVIEW dev. system, it won't exit LabVIEW.