Jump to content

EXE back to buildable project


Recommended Posts

I have updated this message, as after trial-and-error takes I've got success finally!

2020-06-11_16-35-51.jpg.6a185de6f5e3c21e581753297ef44332.jpg

As you can see, the VI is in runnable state and behaves without any errors. My steps to reproduce:

1. Unpacked lvlibp with 7-Zip unarchiver (as I'm on Windows currently) and pulled out "2" file (LIBPLBVW resource).

2. Extracted the inner resource blocks with readRSRC.py -x -i "2" command, got 2.xml, 2_DATA0.bin to 2_DATA4.bin and 2_LVzp.bin files.

3. Unpacked 2_LVzp.bin with an unarchiver, got NI_Embedded_Library.xml and Untitled 1.vi files.

4. Extracted the inner resource blocks from Untitled 1.vi with readRSRC.py -x -i "Untitled 1.vi" command, got Untitled 1.xml and a bunch of various resource sections.

5. Renamed 2_DATA0.bin (from step 2) as Untitled 1_VCTP.bin and placed it near Untitled 1.xml.

6. Added the following text to the end of Untitled 1.xml (before the last </RSRC> tag):

  <VCTP>
    <!-- VI Consolidated Types -->
    <Section Index="0" Format="bin" File="Untitled 1_VCTP.bin" />
  </VCTP>

7. Packed the .xml and all the resources into a single VI with readRSRC.py -c -m "Untitled 1.xml" command, got Untitled 1.vi.

8. Extracted the inner resource blocks from Untitled 1.vi (again!) with readRSRC.py -x -i "Untitled 1.vi" command, got Untitled 1.xml and a bunch of various resource sections (is done to get VCTP processed correctly).

9. Opened Untitled 1.xml and removed everything from <LIBN> to </LIBN> (including the tags as well) changed the library name extension from .lvlibp to .lvlib (between <LIBN></LIBN> tags). To wit, this line

<Library>Untitled Library 1.lvlibp</Library>

should be turned into this

<Library>Untitled Library 1.lvlib</Library>

10. Packed the .xml and all the resources into a single VI with readRSRC.py -c -m "Untitled 1.xml" command, got Untitled 1.vi.

11. Renamed NI_Embedded_Library.xml (from step 3) to Untitled Library 1.lvlib.

12. Opened Untitled Library 1.lvlib in a text editor and altered the lib URL to point to the new location. To wit, this line

<Item Name="Untitled 1.vi" Type="VI" URL="Untitled 1.vi"/>

should be turned into this

<Item Name="Untitled 1.vi" Type="VI" URL="../Untitled 1.vi"/>

13. Opened the VI (LabVIEW did the library reload from the new path and reported), opened .lvlib.

14. In Project Explorer untied the VI from the library w/ RMB -> Remove from Library menu option, saved the both files w/ File -> Save option.

Now the VI runs fine, so it might be a time to simplify this tutorial a little 🙃 If your tools could support lack of VCTP and recreate it automagically, that would be great for sure. :)

Edited by dadreamer
new information
  • Thanks 1
Link to comment
8 hours ago, dadreamer said:

If your tools could support lack of VCTP and recreate it automagically, that would be great for sure.

My intent for 'readRSRC' is to have only two functions:

- Extracting RSRC, without changes, with as little raw binary data as possible

- Re-creating RSRC from extracted data, creating file identical to the one before extraction

So any modifications to the file would have to be in a separate script. Like the one I made for recovering Front Panel - 'modRSRC' (I will probably rename it to fixRSRC at some point).

 

But readRSRC should convert the DATA0 section to XML - that I might do at some point (assuming I will continue to support it long enough).

 

Link to comment

So far I have left those instructions as they are, because I don't know atm, how to eliminate some steps. I believe, there should be a LabVIEW-native way to unlink the VI from the library, thus we could exclude steps 11-14. It would be easier then to automate this algorithm to process multiple VIs. Unfortunately Disconnect From Library method doesn't work on locked libraries and Open VI Reference or even Open.VI Without Refees don't work on broken VIs. There are Linker.Read Info From File and Linker.Write Info To File private nodes also, but I still have not figure out, whether they could be used for the task (any ideas?).

That's why I decided to switch to LEIF formatted lib's and exe's. I found that we can bypass LEIF loader RE-ing using Save.To Buffer private node (always felt uncomfortable studying that loader, because it's rather complex). The node returns convenient RSRC with LVINLBVW block instead of LEIF, so we can easily save that into the file to deal later. I suppose, LEIF data is always translated into common resources by LabVIEW and they're in memory until the VI's are unloaded.

Here's how a single VI may be extracted out of .lvlibp:

extract_lvlibp_BD.png.4d15e2593b4ce49eafe2b52d1ac2a35e.png

extract_lvlibp_vi.vi

And here's how the same may be done with the EXE:

extract_exe_BD.png.a03da887700dbd1ca9188a4cb26c06e5.png

extract_exe_vi.vi

To open VI inside EXE I used technique, described in this article: Passing Data Between LabVIEW Executable Reference VI and a VI

Upd: see next message for the instructions.

On 6/12/2020 at 1:08 AM, Mefistotelis said:

assuming I will continue to support it long enough

I appreciate if you find time to take a look at LEIF binaries some day, as I think you're more experienced in VI contents and internals than me. 🙂 By the way I tried readRSRC.py with LabVIEW 2020 built executable without FFF option and it worked like a charm. I can't do the same with PPL's, because that Fast File Format is forced onto them hardly and I've found no way to switch it off.

Edited by dadreamer
update
Link to comment

Okay, now that is simplified.

To extract VIs out of .lvlibp (no matter, if FFF-enabled or not):

  1. Open extract_lvlibp_vis.vi (attached -> extract_lvlibp_vis.vi ), set path to your PPL (.lvlibp) and the destination folder and run the VI. The files should be extracted and placed to the chosen folder.
  2. Extract the inner resource blocks from a single VI with readRSRC.py -x -i "YourVI.vi" command. YourVI.xml and a bunch of various resource sections should appear.
  3. Open YourVI.xml and change the library name extension from .lvlibp to .lvlib (between <LIBN></LIBN> tags). Remember the .lvlib name. Save and close the .xml.
  4. Pack the .xml and all the resources into a single VI with readRSRC.py -c -m "YourVI.xml" command. You should get YourVI.vi recreated. Do not open it yet.
  5. In LabVIEW create new empty library and save it into the same folder, where YourVI.vi resides. Use that name, you obtained on the step 3.
  6. Now drag YourVI.vi from the folder into the library's root. LabVIEW should reload the VI from the new path and report.
  7. * Untie YourVI.vi from the library w/ RMB -> Remove from Library menu option, save both files w/ File -> Save option. Now you may close YourVI.vi and open again to make sure, it's not broken.
  8. Optionally repeat the steps 2-7 for any other VIs from that .lvlib.

To extract VIs out of .exe (for non-FFF EXE's you finish on the 4th step):

  1. Open YourApp.ini and add two lines to its end according to this article.
  2. Launch YourApp.exe and leave it in this state.
  3. Open extract_exe_vis.vi (attached -> extract_exe_vis.vi ), set path to the destination folder and run the VI. The files should be extracted and placed to the chosen folder. Make sure, you're using the same port number, that you've set on the step 1. If 3364 doesn't work for some reason, try another number (3363 etc.).
  4. For EXE's without FFF option: Now you may open your VIs and make sure, they are fine. For EXE's with FFF: go to step 5.
  5. Load a single VI into flarn's Resource Editor. ("Load" button).
  6. Find CLIv resource section and change its Type to LIvi.
  7. Find CLId resource section and change its Type to LIds.
  8. Save the VI with "Save" button. Don't do any other actions here like fixing checksums or whatever. Now you may open YourVI.vi to make sure, it's not broken.
  9. Optionally repeat the steps 5-8 for any other VIs from that .exe.

* N.B.: In projects with more or less complex hierarchies it might be a good idea not to untie your VIs from the library, because it's very easy to mess with the correct order of such an unlinking. When done incorrectly, your VIs could become broken and to fix them you have to recreate the original VI(s) from the .lvlibp. Also to note, such an untying doesn't work neatly for VIs of different levels of dependence, i.e., a VI has some SubVI(s) and they all are contained into that .lvlibp; on unlinking them you'll likely get those SubVI(s) fine and the main VI broken. But if you really want to detach each and every VI from the library, you first make sure, that your VI is working fine inside that library, then unpack the VI with readRSRC.py, in .xml remove lines like <String>Untitled Library 1.lvlib</String> in LIvi and LIds sections, then pack again to VI, move dependent SubVI(s) out of the library and open up the main VI. It may work or may not, you test it out by yourself.

Edited by dadreamer
add some remarks
Link to comment
  • 3 weeks later...
1 hour ago, pawhan11 said:

@Mefistotelis did You by any chance see how paths to dependencies are stored inside exe/packed libraries? Now I have to move entire hierarchy of PPLs to make this work. What is interesting if dependent PPL is stored on another drive it uses absolute path instead of relative...

That's the standard procedure for path storing in LabVIEW. If the path root is different, LabVIEW will normally store the abolute path, otherewise a relative path relative to the entity that contains the path.

Using relative paths is preferable for most things, but can have issues when you try to move files around outside of LabVIEW (or after you compiled everything into an exe and/or ppl). But absolute paths are not a good solution either for this.

LabVIEW also knows so called symbolic path roots. That are paths starting with a special keyword such as <vilib>, <instrlib>, and similar. This is a sort of relative path to whatever the respective path is configured in the actual LabVIEW instance. They refer by default to the local vi.lib, inst.lib and so on directories but can be reconfigured in the LabVIEOW options (but really shouldn't unless you know exactly what you are doing). Chances to mess up your projects this way are pretty high.

Edited by Rolf Kalbermatter
Link to comment

  

54 minutes ago, pawhan11 said:

id You by any chance see how paths to dependencies are stored inside exe/packed libraries?

Yes. Extract your file, and paths will be in XML.

"LVPath" is actually a class, which is instantiated for many things. So all paths basically have the same structure.

I export it to XML as list of strings - this is how it is really stored. Elements in the list are either normal strings, or tags which LV replaces with value from current config. Example:

  <LIvi>
    <!-- LinkObj Refs for VI -->
    <Section Index="0" Format="inline">
      <LVIN Unk1="NI_InternetTK_Common_VIs.lvlib:Close Calling VI's Windows.vi" Unk2="">
        <!--  VI To Lib Object Ref  -->
        <VILB LinkSaveFlag="2">
          <LinkSaveQualName />
          <LinkSavePathRef Ident="PTH0" TpVal="0">
            <String>&lt;vilib&gt;</String>
            <String>addons</String>
            <String>internet</String>
            <String>NI_InternetTK_Common_VIs.lvlib</String>
            </LinkSavePathRef>
          </VILB>
        </LVIN>
      </Section>
    </LIvi>

 

Link to comment

Thx @Rolf Kalbermatter, is there any magic trick that will allow me to use absolute path instead of relative when they have common root? Or define list of paths where PPL will try to find dependencies? I can edith this in lvlroj file but after save it is replaced back to relative. If I place lvlibp in lvlib folder it will be resolved using tag?

@Mefistotelis those special tags like &lt;vilib&gt; are somehow predefined in LV? Can I create my own custom tags that LV will understand? Or something like probing or assemblyresolve in c#?

Problem i am trying to address is that i ve 2 applications and one has public.lvlibp interface that can be used by another one. To make this work app 2 must have relative path to public.lvlibp after build and deployment... 

 

Link to comment
10 minutes ago, pawhan11 said:

those special tags like &lt;vilib&gt; are somehow predefined in LV?

Yes. "&lt;" and "&gt;" are just symbols used to allow storage in XML; these are so-called HTML Entities. So this string really is "<vilib>".

10 minutes ago, pawhan11 said:

Can I create my own custom tags that LV will understand? Or something like probing or assemblyresolve in c#?

No idea. There are more tags which can be used, but I never cared for listing them, or checking whether they're all hard-coded.

EDIT: Reading @Rolf Kalbermatter answer above, I see he already answered this.

 

 

Edited by Mefistotelis
Link to comment
  • 2 weeks later...

At the end of the video you don't go too much into details about the missing block diagrams, I also noticed that the icon of the subvi is missing - that's not very important - but I was wondering if the connector pane is available, which leads me to my next question : after recreating the VIs from the EXE, if you replace the subVI with a newly created one with the same connector pane, are you able to generate the EXE?

Link to comment

nice demo.  Well done.

I appreciate the works and your passion for your work.  I know you are showing this as proof of concept and it is great work and progress so far.   It maybe helpful to think of these points below while you are doing your LabVIEW RE.   

  1. Simple subVIs with more connector pane wired. 
  2. Dynamically called subVIs
  3. Classes/Objects
  4. more complex diagram functions. 
    1. Loops,events,Qs,.Net Assemblies,  etc.
  5.  Much more complex projects.  example 5k-10k subVI.
    1. Projects with Realtime components. 

also bug fix:  at 12:57. the numeric values show "1,1" instead of "1".

Link to comment

  

29 minutes ago, Antoine Chalons said:

At the end of the video you don't go too much into details about the missing block diagrams

Oh, going into that is definitely not for 15 minutes video. Recovering it completely and automatically, for every VI - would be a project for several months (considering this is my afternoon project). It's way easier to make partial recovery, requiring the user to finish. And just placing block diagram with the components we've already recovered for FP - is trivial.

36 minutes ago, Antoine Chalons said:

I also noticed that the icon of the subvi is missing - that's not very important

Yeah, noticed that as well.. the whole connectors pane is very easy to handle, I will likely fix that in the nearby future.

37 minutes ago, Antoine Chalons said:

after recreating the VIs from the EXE, if you replace the subVI with a newly created one with the same connector pane, are you able to generate the EXE?

Yes. That is probably the main use of that solution - recover the project without Block Diagrams, then re-create only VIs that need updating, and re-build everything.

 

Link to comment
14 minutes ago, sam said:

I know you are showing this as proof of concept and it is great work and progress so far.

Yes. What I didn't mention in the video is - ATM the tool only supports the specific components I put into project. I didn't even looked at other controls yet. And for various flavors of numeric/boolean controls - all we can figure out is whether that's a control or indicator, the specific visual representation of the switch is lost - recovered one always looks the same.

 

14 minutes ago, sam said:

It maybe helpful to think of these points below while you are doing your LabVIEW RE.

Thank you, will consider that. Complex projects are already supported - you just need `find` to list all extracted files, and do the 3 actions for each of them: extract to XML, recover FP, re-create VI.

 

14 minutes ago, sam said:

also bug fix:  at 12:57. the numeric values show "1,1" instead of "1".

Default data type for that numeric control is Double. For this type, my tool sets an increment of 0,1. If it was Integer, the increase would be 1. The original value of that increment is lost with the removal of FP.
 

Edited by Mefistotelis
Link to comment
  • 6 months later...
On 7/15/2020 at 5:42 AM, Mefistotelis said:

 

Hello,

I tried executing above commands in Git Bash and found that for one the EXE, after executing "./readRSRC.py -vv -x -i 1.exe_10_2_0" command I am getting "1_LANG.bin" and "1_LEIF.bin" but it is not generating "1_LVzp.bin"

Below is a log generated....

$ ./readRSRC.py -vv -x -i 1.exe_10_2_0
1.exe_10_2_0: Starting file parse for RSRC extraction
1.exe_10_2_0: Block 'FLAG' index 0 recognized
1.exe_10_2_0: Block b'FLAG' max data size set to 32 bytes
1.exe_10_2_0: Block b'LANG' max data size set to 24 bytes
1.exe_10_2_0: Block b'LEIF' max data size set to 10979932 bytes
1.exe_10_2_0: Writing block b'FLAG'
1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1500
1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1501
1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1502
1.exe_10_2_0: Writing inline XML for block b'FLAG' section 1550
1.exe_10_2_0: Writing block b'LANG'
1.exe_10_2_0: Storing block b'LANG' section 0 binary in '1_LANG.bin'
1.exe_10_2_0: Writing block b'LEIF'
1.exe_10_2_0: Storing block b'LEIF' section 0 binary in '1_LEIF.bin'
1.xml: Writing binding XML
 

 

Could you please help me to know if there any reason for not generating LVzp.bin file and how to solve this.

Thank you.

Link to comment
  • 2 weeks later...
On 2/6/2021 at 7:20 PM, dadreamer said:

To extract the VIs out of LEIF section (produced by Fast File Format option) you may try my instruction above.

Hi Dadreamer,

 

Thank you for your suggestion. I followed your instructions and found that "extract_exe_vis.vi" works fine with .VI and .CTRL extensions but my exe contains .xctl (Xcontrols) and some .lvclass and this vi is throwing errors while saving it. (Due to path problems)

E.g.

Tab.lvclass:Tab.ctl

Tab.lvclass:GetSubPanelViRef.vi

ADC_AcqView.lvlib:SaveData.vi:Instance:2

Analysis.lvlib:ADC_Debug_Gen.vi:Instance:1

PagesArea.xctl:RenderPageMoveData.ctl
PagesArea.xctl:ForceRender.vi
 

could you please look into this and help me to resolve it?

Thank you.

Best Regards,

Sagar Doshi.

Edited by sagardoshi65@gmail.com
Link to comment
3 hours ago, sagardoshi65@gmail.com said:

this vi is throwing errors while saving it. (Due to path problems)

You may easily overcome this with the following modification.

2021-02-16_17-31-17.jpg.352e7eecd6f7deb3fd1cd9383b7b7456.jpg

But you also will need all .xctl and .lvclass' files (that are plain XML after all) from the exe, otherwise your linked VIs won't open properly. Sadly I don't know the way to pull out such files from a LEIF, because App.ExportedVIs property does not return them. I'm not saying now, that you have to recreate .xctl/.lvclass from a scratch, as they are actually stored inside the exe. But the way to extract them is yet to be found.

Link to comment
15 hours ago, dadreamer said:

You may easily overcome this with the following modification.

Thank you Dadreamer, I appreciate your help. Now at least i can see all used vis, controls in the folder. But could not open them.

I tried Loading a single VI into flarn's Resource Editor and changed CLIv resource section Type to LIvi. and CLId resource section Type to LIds. But still could not open the VI. I am getting below error.

image.png.cf025c22cc9f885a114585c42052a890.png

 

 

Link to comment

It's difficult for me to figure out the reasons behind your situation as I don't have your application and cannot do some tests with it. To me it looks like you don't have all the necessary dependencies extracted, thus LabVIEW fails to open the VI (assuming that you've done every step from the instruction properly). Are you receiving the same message when placing that VI onto the BD of a brand new VI?

Well, I spent some time searching for ways to extract project library files (.lvlib, .xctl, .lvclass) and seems I found one. You might try to complete your file list by doing the following steps.

1. Install Full Featured Run-Time Engine (FF RTE) for your LabVIEW. You may find this package in your installation ISO, e.g. for LV 2019 it is ni-labview-2019-ff-runtime-engine-x86_19.* package from pool folder of LV19 image.

2. Go to C:\Program Files (x86)\National Instruments\Shared\LabVIEW Run-Time\2019 folder (for 32-bit LabVIEW 2019). If you have 64-bit LabVIEW, then you go to Program Files without (x86) ending. There you should have both lvrt.dll and lvffrt.dll.

3. Temporary rename lvrt.dll to some other name and make a copy of lvffrt.dll. Rename that copy to lvrt.dll. Now LabVIEW will start FF RTE when running executables instead of a common RTE.

4. Open your exe and put it into a stopped state (Run button should not be pressed).

5. Now you need to craft a dummy .xctl/.lvclass with the same name, that's assigned to the .xctl/.lvclass, you want to extract. That .xctl/.lvclass should already be loaded into the app's memory. As soon as it's crafted, open it in the same app with File -> Open menu entry. You should receive the following window along with some message.

2021-02-18_16-22-21.jpg.9e66535af2ae22cc34c27294a1e2f4b4.jpg

6. Now you may save the project library with File -> Save Project menu entry. RTE will say, that it's unable to save inside the executable and offer you a browse dialog to choose the path to save.

7. Place that .xctl/.lvclass near other VIs (Data.ctl, Facade.vi etc.) and try to open it in a common LabVIEW. On opening it should relink all the files, then you save everything.

8. As a bonus you may try to save the main VI or some subVIs, it uses (File -> Save and View -> VI Hierarchy / Browse Relationships entries). But be prepared for RTE to crash suddenly, because it does not always go firmly. ;) For me it did not want to save XControl files at all.

 

Maybe this hack will work for you or you will find a working combination of few techniques... There are not so many LV users, who ever thought of tearing down the exe's, not even saying about bringing the resulting files to a workable state.

Link to comment
  • 2 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.