Developer Center Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

The palette api and mnu binaries

First off, for all the cool things we can do with Labview, I really hate the hoops we have to jump through to create palettes for reusable code modules.  So with that out of the way...

I've been trying to develop a tool I can use to more easily create and manage the palettes for each reuse project.  I have a simple prototype that reads and writes mnu files, I just hasn't been able to create mnu files that behave correctly using my intended workflow.  The more I dig into this to try to figure it out the more questions come up.  Here are some things I've noted.  Confirmations and corrections are most welcome.

Error Handling

Error handling in the palette api appears to be non-existent.  I don't think I've ever had the Write Palette vi generate an error.  Instead it just quietly quits processing the mnu file.  I need to validate all the inputs before calling it, or manually verify the resulting mnu file is what I expect.

<<file not found>>

I expected this would create a slightly different mnu file, perhaps embedding a tag in the binary file for those items that were not found.  I was wrong.  It appears this tag is not included in the binary at all.  I created two mnu files with the only difference being all the item paths in one of them were appended with <<file not found>>.  A binary comparison showed the resulting mnu files were identical.  Oddly, appending <<file not found>> to the pathsresulted in the mnu file being created in ~1/10th of the time as the other mnu file.  Clearly the tag bypasses some sort of internal processing steps, probably something with references given the amount of time it takes.  My tests haven't revealed what I might be missing if I choose to always append the tag.  Any hints?

Item Paths

The item paths returned from Read Palette always show an absolute path, but the paths in the mnu binary are not absolute.  If the item is located in vi.lib, user.lib, or instr.lib (maybe others?) the binary path includes symbolic links to those directories.  If the item is not located in those directories, the binary path is a relative path from the .mnu file to the item location.  (This confused me for a while.  Thanks Ton for pointing me in the right direction here.)

Paths to Libraries and Library Items

If an item is part of a library and the library path is filled in, the item path is relative to the library, not the mnu file.  During testing I had an item included in one library but accidentally set the library path for another library.  As I recall the mnu file built just fine... not sure what problems (if any) that would cause down the road.

Symbolic Paths

Can't use LV symbolic paths in the Write Palette vi.  It will create a mnu file but the paths will be nonsense.

mnu File Location

There are some weird thing I'm seeing that imply a hidden dependency on where the mnu file is saved to.  Using the <<file not found>> tag I created 3 palettes to the same set of non-existent vis.  Some of the fake vis are (ostensibly) located in my dev scc folder, some are located in vi.lib, and some are located in a folder on my desktop.  Each of the three palettes points to all the vis in those three locations.  One of the mnu files is created in my dev scc folder, one in user.lib, and one in the folder on my desktop.

As long as the mnu files remain in those directories they all return the same item paths from Read Palette.vi.  However, if I create copies of the mnu files and move them to other locations the item paths start returning odd results.  For example, moving the mnu file from user.lib to my desktop and reading it gives me paths like...

     scc:\dev\Palette Sandbox\MyClass1\fake\MyClass1.lvclass<<file not found>>

for the vis in my dev scc directory, and...

     Users:\daklu\Desktop\palette_sandbox\MyClass3\fake\MyClass3.lvclass<<file not found>>

for the vis in the folder on my desktop.  Are Users: and scc: symbolic os links?  Private internal symbols for LV?  A bug in the api?

0 Kudos
Message 1 of 7
(8,336 Views)

Hello Daklu,

The palette editor is definitely on our group's list of "wants" from R&D and I really appreciate the feedback.

For each of your topics I'll provide some quick comments/answers and there are a few items I'll need to follow-up with developers for...

Error Handling

This is excellent feedback and I'd like to file a CAR ASAP. If you have any specific examples you can either list out or send to me at robert.des.rosier@ni.com, I'd really appreciate it.

<<file not found>>

It is my understanding that appending <<file not found>> to an item path will allow the item to still get added to a .mnu file. Without this tag, a file that does not exist will be excluded. I'm not sure what the difference in processing would be, but I will check with one of the developers involved with this API.

Item Paths

Where 'Write Palette.vi' will accept any type of path (absolute, relative, or symbolic), the 'Read Palette.vi' only returns the absolute path. I'm not sure what Ton said (link doesn't work for me), but from what you've found in the binary it sounds like the file path (absolute, relative, or symbolic) written to 'Write Palette.vi' is what is actually stored in the .mnu file and 'Read Palette.vi' is making the conversion. I'll follow-up with a developer to confirm this behavior and to find out why the actual path stored in the .mnu file is not returned.

Paths to Libraries and Library Items

I agree, an error probably should be thrown when an item and library are not related.

Symbolic Paths

I did not see symbolic paths were an issue with 'Write Palette.vi'. Could you please provide me with an example?

mnu File Location

I was also unable to reproduce this behavior, the steps I followed were to:

  1. Create a palette on my desktop with an item path for <userlib>:\test1.vi<<file not found>>
  2. Read the palette before copying, path given as C:\Program Files (x86)\National Instruments\LabVIEW 2009\user.lib\test1.vi<<file not found>>
  3. Copy the .mnu file to another location on disk (I tried the root C: and my dev folder C:\dev\) and read the palette, and I am still given the correct path (C:\Program Files (x86)\National Instruments\LabVIEW 2009\user.lib\test1.vi<<file not found>>)

-Bob

0 Kudos
Message 2 of 7
(5,204 Views)

Some of these things make more sense once I understand the internal structure of the mnu file.  Unfortunately there's very little information available on how palette information is actually stored.

Error Handling

Use cases that don't generate an error?  I... I've never been asked for that...

The main use case I've run across is not generating a palette item if it can't find it.  I had incorrectly thought it silently aborted since on my test palettes it would either find all the items or none of them.  Since we have to append a tag to create items that are not found, I would expect an error (or at least a warning) if it can't find an item that I, as the api user, expect to be there.

<<file not found>>

"I'm not sure what the difference in processing would be, but I will check with one of the developers involved with this API."

Tell them to look in CheckViForLib.vi.  (Something like that... the exact name escapes me at the moment.)

Symbolic Paths

I wasn't using the correct syntax for the symbolic path in my test.  I had left out the colon.  Symbolic paths appear to work just fine. 

Come to think of it, leaving out the colon created an invalid path.  For example, if I create test.mnu on my desktop that contains a single item with the path set to

     <vilib>\MyTest.vi<<file not found>>          (I intentionally omitted the colon)

save the file, then read it back, I get

     C:\Users\daklu\Desktop\test.mnu\<vilib>\MyTest.vi<<file not found>>

Clearly that's a nonsensical path that will never be found.  Should the api at least check that the paths are valid?

mnu File Location

Some more experimentation indicates this is an issue with relative paths.  When the mnu file contains an item path that can't be reached because the path has too many 'up directory' commands, the results are unpredictable.  Here's how to replicate:

1. Create a new test.mnu file in C:\Program Files\National Instruments\LabVIEW 2009\user.lib  (any deeply nested directory will do)

2. Include paths for two items:

     C:\Users\daklu\Desktop\test.vi<<file not found>>

     C:\test.vi<<file not found>>

3. Save the file.

4. Read the file.  Note the paths are correct.

5. Copy the mnu file to C:\Users\daklu\Desktop\test.mnu.

6. Read the file and note the paths are now

     Users:\daklu\Desktop\test.vi<<file not found>>

     test.vi:\<<file not found>>

New Issue:  Class Membership

Today I figured out that although a mnu file can be made part of a project library, it appears it does not take on that library's namespace.  This led to my built libraries and deployed libraries to continue to use the mnu file in my source directory as the default palette since a mnu file of the same name (from my source code) was already in memory.  Naturally I assumed the class stored the default palette name as an absolute path, which created more confusion when moving around classes and mnu files independently didn't result in behavior explained by either absolute paths or relative paths.  Is it possible for mnu files to take on the library's namespace?

(No, I don't want to put this on the idea exchange... marketing would completely submarine any chance of it being implemented when the see it only received three kudos.)

"I'll follow-up with a developer to confirm this behavior and to find out why the actual path stored in the .mnu file is not returned."

This is really what's important to me.  As a reusable code developer I'm not interested in where the mnu file is looking for items based on it's current location.  I want to know where it will look for items when I move it to another directory.  It doesn't have to be a change to the api.  As long as I'm sure I understand what path information is actually being stored in the mnu binary I can modify my tool to present that to the user.

0 Kudos
Message 3 of 7
(5,204 Views)

Daklu wrote:

Some of these things make more sense once I understand the internal structure of the mnu file.  Unfortunately there's very little information available on how palette information is actually stored.

Error Handling

Use cases that don't generate an error?  I... I've never been asked for that...

The main use case I've run across is not generating a palette item if it can't find it.  I had incorrectly thought it silently aborted since on my test palettes it would either find all the items or none of them.  Since we have to append a tag to create items that are not found, I would expect an error (or at least a warning) if it can't find an item that I, as the api user, expect to be there.

I've pointed this out to the developer and am awaiting a response. Currently, I believe this behavior is documented in the LabVIEW Help, but I would also like to see a warning or error when an item is excluded or ignored.






<<file not found>>




"I'm not sure what the difference in processing would be, but I will check with one of the developers involved with this API."




Tell them to look in CheckViForLib.vi.  (Something like that... the exact name escapes me at the moment.)

The developer confirmed items are processed differently depending on whether or not the path includes the <<file not found>> tag. If the file does not have this tag, the Palette API will check whether the item exists at the specified location, whether it is a valid file to add, and will read some information from the file (such as whether or not it is in an lvlib). For the <<file not found>> tag, none of these checks are performed and therefore execution speed will be different as file I/O is not performed (unless perhaps you're using a lightning fast solid-state disk ).






Symbolic Paths

I wasn't using the correct syntax for the symbolic path in my test.  I had left out the colon.  Symbolic paths appear to work just fine. 

Come to think of it, leaving out the colon created an invalid path.  For example, if I create test.mnu on my desktop that contains a single item with the path set to

     <vilib>\MyTest.vi<<file not found>>          (I intentionally omitted the colon)

save the file, then read it back, I get

     C:\Users\daklu\Desktop\test.mnu\<vilib>\MyTest.vi<<file not found>>

Clearly that's a nonsensical path that will never be found.  Should the api at least check that the paths are valid?

Since the <<file not found>> tag is used, none of the checks mentioned above are performed (if they were, the item would not be added) and since the API did not recognize <vilib> as a symbolic path location it treated it as a regular folder name. The check could be included in the API or a check could be implemented in the code leading up to Write Palette.vi; I'll pass on this feedback.

mnu File Location

Some more experimentation indicates this is an issue with relative paths.  When the mnu file contains an item path that can't be reached because the path has too many 'up directory' commands, the results are unpredictable.  Here's how to replicate:

1. Create a new test.mnu file in C:\Program Files\National Instruments\LabVIEW 2009\user.lib  (any deeply nested directory will do)

2. Include paths for two items:

     C:\Users\daklu\Desktop\test.vi<<file not found>>

     C:\test.vi<<file not found>>

3. Save the file.

4. Read the file.  Note the paths are correct.

5. Copy the mnu file to C:\Users\daklu\Desktop\test.mnu.

6. Read the file and note the paths are now

     Users:\daklu\Desktop\test.vi<<file not found>>

     test.vi:\<<file not found>>

CAR 219295 has been filed.

New Issue:  Class Membership

Today I figured out that although a mnu file can be made part of a project library, it appears it does not take on that library's namespace.  This led to my built libraries and deployed libraries to continue to use the mnu file in my source directory as the default palette since a mnu file of the same name (from my source code) was already in memory.  Naturally I assumed the class stored the default palette name as an absolute path, which created more confusion when moving around classes and mnu files independently didn't result in behavior explained by either absolute paths or relative paths.  Is it possible for mnu files to take on the library's namespace?

(No, I don't want to put this on the idea exchange... marketing would completely submarine any chance of it being implemented when the see it only received three kudos.)

Very interesting. I'll need to reproduce this behavior and file a CAR because even if this is expected behavior I've not seen it documented anywhere and it needs to be. If you can provide a set of steps to demonstrate this it would help.

"I'll follow-up with a developer to confirm this behavior and to find out why the actual path stored in the .mnu file is not returned."

This is really what's important to me.  As a reusable code developer I'm not interested in where the mnu file is looking for items based on it's current location.  I want to know where it will look for items when I move it to another directory.  It doesn't have to be a change to the api.  As long as I'm sure I understand what path information is actually being stored in the mnu binary I can modify my tool to present that to the user.

I've received some information from the developer, but I have follow-up questions to obtain a complete answer for you...some interesting information is the Write Palette.vi actually tries to convert absolute paths to a symbolic or relative path before writing the mnu file. So the paths in the mnu file are not always the same as what was passed into the Write Palette.vi (I've requested documenting this in the Help). Also, for cases where you read from an mnu file in absolute paths, modify item data, and write the cluster back to the mnu file the existing relative and symbolic paths will not be overwritten with absolute paths as the API prefers a symbolic or relative path and will not overwrite them with absolute paths. The reasoning behind returning the absolute path was for ease-of-use so users do not have to convert from symbolic/relative before they can manipulate the paths; I've asked if a switch could be added for API and reusable code developers who are interested in reading the actual paths stored in the mnu file...more to come.

0 Kudos
Message 4 of 7
(5,204 Views)

I love how accessable NI's developers are and how freely they share information with users.

Error Handling

Currently, I believe this behavior is documented in the LabVIEW Help, but I would also like to see a warning or error when an item is excluded or ignored.

You're right.  I went back and checked.  We developers are notoriously bad at reading documentation.    Still, the decision to simply not add an item to the mnu file if it can't find it sounds like it was made based on how the api is used internally rather than looking at the api as an independent entity.  (Or maybe my use case is way out in left field.)

Yesterday I had an issue where I was writing a mnu file without an error.  Reading it back raised an "Invalid mnu file" error.  So far I've been unable to reproduce it on my computer at home but I'll let you know if I do.

<<file not found>>

If the file does not have this tag, the Palette API will check whether the item exists at the specified location, whether it is a valid file to add, and will read some information from the file (such as whether or not it is in an lvlib).

So if I give an item a path to a vi that is a member of a library and don't include the library path, Write Palette finds the owning library and writes the path to the library path field.  In the same situation if I append <<file not found>> to item path the library path field isn't populated.  I'm guessing a palette item's owning library needs to known so the palette can show the 'x' emblem if the active vi doesn't have the proper scope to use that palette item.  Are there other reasons the owning library needs to be known?

It sounds like as long as I make sure the path and library path fields point to valid items I can add the <<file not found>> tag and get the same mnu binary file as I would without the tags.  (My tests indicated that but I haven't tried testing corner cases.)

Symbolic Paths

Since the <<file not found>> tag is used, none of the checks mentioned above are performed (if they were, the item would not be added) and since the API did not recognize <vilib> as a symbolic path location it treated it as a regular folder name. The check could be included in the API or a check could be implemented in the code leading up to Write Palette.vi; I'll pass on this feedback.

I see.  <<file not found>> bypasses all checks, not just the check to make sure the file exists.  As an api user I find Write Palette VI to be undecided whether it's a high level api (not adding items if they are not found) or a low level api (not checking that a path is even possible.)

mnu Namespacing (was Class Membership)

I'll need to reproduce this behavior and file a CAR because even if this is expected behavior I've not seen it documented anywhere and it needs to be. If you can provide a set of steps to demonstrate this it would help.

I've attached a project that includes the vis needed to repro and a text file explaining the repro steps demonstrating that the mnu file is not part of the library's namespace.  It's possible to work around this particular use case... it's more a matter of expecting namespaces to extend to mnu files and it not being documented that they are not.

(Potential use case I have not tried:  What happens if I create a default dir.mnu for all the directories where I distribute my reuse classes and try to set the default menu for those classes to dir.mnu?)

Returning Relative Paths

The reasoning behind returning the absolute path was for ease-of-use so users do not have to convert from symbolic/relative before they can manipulate the paths; I've asked if a switch could be added for API and reusable code developers who are interested in reading the actual paths stored in the mnu file...more to come.

Converting between symbolic and actual paths can be a pain, so I think the decision makes sense for those users who are creating mnu files for deployed code.  (Which admittedly is probably the majority of the users.)  It turns out adding a switch to Read Palette VI isn't needed.  I poked around in Palette Menu.lvlib and discovered it's pretty easy to get the relative/symbolic paths from the mnu file.  (See my Read mnu File(no path conversion).vi)  As long as there aren't any plans to restrict the scope of those vis I'm good.

If you do end up locking up those vis, rather than adding a switch to the Read Palette VI I'd prefer a different set of "advanced" vis that allow more direct mnu file manipulation.  As a developer I prefer there to be a clear difference between high level api methods and low level api methods.

(Incidentally, can you share what PLM2, CPST, and LPTH refer to in the Palette Menu library?)

0 Kudos
Message 5 of 7
(5,204 Views)

Daklu wrote:

<<file not found>>

So if I give an item a path to a vi that is a member of a library and don't include the library path, Write Palette finds the owning library and writes the path to the library path field.  In the same situation if I append <<file not found>> to item path the library path field isn't populated.  I'm guessing a palette item's owning library needs to known so the palette can show the 'x' emblem if the active vi doesn't have the proper scope to use that palette item.  Are there other reasons the owning library needs to be known?

It sounds like as long as I make sure the path and library path fields point to valid items I can add the <<file not found>> tag and get the same mnu binary file as I would without the tags.  (My tests indicated that but I haven't tried testing corner cases.)

I've asked the developer to explain the algorithm used and to include this in the documentation, I'm not exactly sure how in-depth the checks are at this point.

Symbolic Paths

I see.  <<file not found>> bypasses all checks, not just the check to make sure the file exists.  As an api user I find Write Palette VI to be undecided whether it's a high level api (not adding items if they are not found) or a low level api (not checking that a path is even possible.)

I agree. I'd like to see some changes made to the API to address this.

mnu Namespacing (was Class Membership)

I've attached a project that includes the vis needed to repro and a text file explaining the repro steps demonstrating that the mnu file is not part of the library's namespace.  It's possible to work around this particular use case... it's more a matter of expecting namespaces to extend to mnu files and it not being documented that they are not.

(Potential use case I have not tried:  What happens if I create a default dir.mnu for all the directories where I distribute my reuse classes and try to set the default menu for those classes to dir.mnu?)

CAR 219648 has been filed.

Returning Relative Paths

Converting between symbolic and actual paths can be a pain, so I think the decision makes sense for those users who are creating mnu files for deployed code.  (Which admittedly is probably the majority of the users.)  It turns out adding a switch to Read Palette VI isn't needed.  I poked around in Palette Menu.lvlib and discovered it's pretty easy to get the relative/symbolic paths from the mnu file.  (See my Read mnu File(no path conversion).vi)  As long as there aren't any plans to restrict the scope of those vis I'm good.

If you do end up locking up those vis, rather than adding a switch to the Read Palette VI I'd prefer a different set of "advanced" vis that allow more direct mnu file manipulation.  As a developer I prefer there to be a clear difference between high level api methods and low level api methods.

(Incidentally, can you share what PLM2, CPST, and LPTH refer to in the Palette Menu library?)

Glad to hear you found a workaround; I'd still like the API to provide users with an option to read a mnu file and return the exact contents of the mnu rather than converting the paths. I'm currently waiting on a response from the developer, in the meantime I'll try to find the password for the VIs to figure out what PLM2, CPST, and LPTH are used for.

0 Kudos
Message 6 of 7
(5,204 Views)

Sorry for the delay on this response.


1. I filed a CAR to implement a warning when Write Palette.vi does not add an item due to an invalid path.

2. When files are appended with <<file not found>>, the developer believes the user should take responsibility for the item path. The VI will not perform any checks on paths with <<file not found>>, this tag is intended as a flag to tell the API that the user knows the path is not valid, I've asked for clearer documentation to explain this.

3. I've filed a CAR to address the issue of reading the actual paths stored in the mnu file, and this is targeted for a future release.

Do you still need an explanation for PLM2,  CPST, and LPTH?

0 Kudos
Message 7 of 7
(5,204 Views)