Jump to content

smenjoulet

Members
  • Posts

    126
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by smenjoulet

  1. My first cut was for the engine have a single event of the parent EventData class type. I passed the appropriate child EventData object into the Generate User Event prim. Client code called EventData:GetName to return a unique string and had to case out the event data based on that.

    post-7603-126353647484_thumb.png

    This is okay and probably would have worked for my immediate requirements. I'm not real happy with it though because casing out on a string is a runtime bughole I'd prefer to keep closed. As a general purpose technique it also doesn't allow clients to selectively register/unregister for events at runtime. The client has to decide at design time which events will be handled. At runtime the only choice is to either handle all of those events or none of them.

    Why can't you dynamically dispatch off the user event and resort to casing out based on class name. DD works for me. See attached. I guess Stephen alluded to this in his post.

    I've often wondered why I haven't been able to add or remove user events that are registered to an event structure. If the Register for Events prim behaves similarly to the Bundle (not Bundle by Name) prim, then that explains a lot. I still wish there were a built-in way to filter user events at runtime, but at least I have (I think) a better understanding of the current behavior.

    Not sure if I'm really answering your question or just misunderstanding, but you can register/unregister for user events during runtime. Doesn't that qualify as add/remove. Again, see attached. I apologize if I'm not following you completely.

    Thinking about this also made it clear to me why we cannot ever support polymorphism of the user event wires. It is the wires themselves that propagate the types to the Event Structure. Those types have to be known at *compile* time. If you upcast all the wires, it would be no different than if you had created all your events with LabVIEW Object in the first place: you'd loose all the type safety in the Event Structure, and all the events would be named the same.

    blink.gif Then what's going on here in 2009. Am I missing something:

    post-415-126357866506_thumb.png

    Class User Events Folder.zip

  2. No joy here. I cannot get anything back from the System Exec call. It does open a console window and I can see the output in the window as I press the write buttons but when I choose exit and close the app's window, nothing is returned to the calling LV VI. Do you have anything special in your exe's ini file?

    Weird. I get nothing under XP when calling from either LV2009 or 8.6.1. Maybe this is an XP issue. Can you try this on an XP machine and confirm?

    No, nothing special in the ini. In fact you don't even need the ini. I'm on XP and Jim has tried it on Win7.

    What are you using for the command line in System exec? I wouldn't expect a console Window to open (I don't get one), which leads me to believe you are using cmd /c or start on the command line. Just try the path to the exe and see if that works.

    -Scott

    EDIT: I see you've already figured it out. I'm working on the redirection issue. If I get it figured out, I'll post the solution.

  3. Any chance you know of a was to perform the AttachConsole within .NET? It would be nice to get rid of any DLL calls...

    No. If there is a pure .NET way, I haven't found it yet. I haven't searched real hard, so it may still be out there.

    I just tried building you exact code into an exe in LV2009 (instead of replicating the functions in 8.6.1 like I did above) and I still cannot get anything returned to the StdOut of the System Exec call from within LV. Are you sure you got that part to work?

    Positive. I just tried it again to be sure. I'm on XP. To be honest, I was a little surprised that it did work. More about that below.

    Also, I think this might be related to the fact that the redirection and piping does not work.

    I don't pretend to fully understand it yet, but my interpretation is that you're not really writing to stdout, but to the console which I think is a distinct but subtle difference. That is why I believe (at this point) that piping and redirection don't work, but also why I was surprised that the .NET WriteLine output appeared on stdout of System Exec (at least for me). There's a contradiction there, so more investigation of what is really happening is needed.

    -Scott

  4. I tried to call this VI (built into an EXE) using System Exec from LabVIEW. The output does not show up in the STDOUT of the System Exec. It seems this only works when there is a console window (which is nice, but doesn't allow the EXE to be called from other applications in a way that lets them read the STDOUT). Did I miss anything?

    Interesting. I haven't looked into it any further but if you use the .NET methods, it does work with System Exec. I've attached an example (LV20009) which allows writing with both kernel32 dll calls and .NET. The writes using the dll will not appear in STDOUT as you found, but the writes using .NET will.

    Also, neither method as used works with redirection or piping, but it might be possible to get that to work as well if someone wanted to investigate it.

    IIRC, The method in Linux of writing directly to dev/stdout with the file functions does support redirection at least (never tried piping).

    -Scott

    Write Std Out Example.vi

  5. BTW: if you also have a .NET solution for writing to the stdout instead of the old school kernel32.dll solution, I would love to see it.

    As far as .NET goes, you can use System.Console to control your console window (write, write line, position cursor, etc.) but unfortunately I think you still need one API call to kernal32.dll for either AllocConsole() or AttachConsole() before any .NET calls.

    You can then either use asbo's solution using start or use the props/methods of System.Console to position the cursor and "erase" part of the screen before writing your text if you're just wanting to make it look nice. The latter is a little hacky.

    If there is a pure .NET solution, I haven't found it, so if you figure it out let us know.

    Incidentally, in Linux I always just used the 'Write to Text File' function with a path of dev/stdout and it worked great.

    -Scott

  6. The bump of this thread has me thinking...

    ...the Penguins won the Stanley Cup...

    Ben

    Boo, I say to that! throwpc.gif

    Here I thought you were a thoughful intelligent human being and then you had to spoil it. shifty.gif

    j/k... Seriously, great series for the Pens. I liked them a lot better after they got rid of that doofus of a coach Michel Therrien. Look forward to three in a row!

    -Scott

    Oh, yes... Kudos to you, Toby, for your accomplishment.thumbup1.gif

  7. ... and in the network bind them.

    Ben

    Nice! thumbup1.gif

    One thing that occurs to me is to have a two-part Spec.exe. One very non-resource-intensive part would run all the time, and when Control.exe demands it (still using VI server?) that part would open up the main part and run that.

    Better ideas welcome. I'm not very TCP-IP / .NET / etc savvy, so if you're going there, dumb it down a bit please.

    While I think the lightwieght exe approach would work great, here's another alternative for you to consider.

    Look at the SysInternals tools (now a part of Microsoft), specifically PsExec.

    This allows you to run processes on remote machines, provided you have the proper access of course, which I assume you would.

    -Scott

  8. This VI cannot access the referenced item because of library access scope. Items in private scope can be accessed only from the following locations:

    1) from inside the owning library or LabVIEW class

    2) from inside a library contained by the owning library.

    Why is that?

    Because it is part of a library and is marked as a private item. Looks like you'll need to use the one from 8.6.

    -Scott

  9. OK, now I see what your problem is and why I didn't see it.

    The exe code works fine if and only if the LV2009 development is not open. Somehow the presence of the development environment is preventing a separate VI Server Instance to function correctly!?!

    In more detail what I see is the the exe standalone will set and read the Port to lets say 4369. If I have the LV DE open first and then open and run the exe

    the port will get set to 4369 but will be read as 3363 (the default LV port)

    The problem is with the default VI server port, not that the IDE is preventing another VI server from functioning correctly. Only 1 server can run on any given port at a time (of course). If you have the VI server set to startup in the exe (per the ini) and don't specify a port, it will try and start at port 3363. If any other VI server (LabVIEW IDE or other exe) is active on that port, then the VI server for that exe won't start. If you try and set the port to a different number later and restart the server, it will generate an error and not start. Actually, in LV2009, it looks like even if the server isn't enabled in the ini, you can't restart it later on a different port. That may be the intended action by NI for some reason, but it seems like a bug to me and I don't recall how it worked in earlier versions.

    In either case, the property node for server port will return 3363, even though the node didn't generate an error when trying to set it to a different number. That also seems like a bug to me.

    The reason I didn't have any problems on my end initially: I never run my IDE on the default port!

    So how to fix it...

    Use a defined startup port that the VI server for the exe will start on. This is only for startup so it won't conflict with any other instances of your exe.

    Find an unused port and reset the VI server to use that port instead of your startup port.

    That frees the startup for use when another instance of your exe launches.

    Hope that helps!

    -Scott

  10. I added a little bit of code to read back the current server port in my snippet and it returns the value I last set.

    As for actual testing, I open a connection to the exe from LabVIEW and ask it for some information (e.g. exported VI's in memory). If the port I'm using in LabVIEW doesn't match the port setting last used in the exe, it doesn't work. When they match, success!

    -Scott

  11. I have been beating my head against the wall for 2 weeks frusty.gif over this issue and so far I cannot get an answer to this question and its import.

    Basically I have found that I cannot set the app class property Srvr.Port within a LV2009 executable. The property node executes without error

    but I have verified that the VI Server Port is not being set and thus always remains at the default of 3363.

    Any insight would be greatly appreciated, thanks.

    Yes, you can. See the attached snippet. Just drop it in a project and make a build. You can also put it in the ini as Antoine explains, but this allows you change it on the fly or keep it private, if that is your intent.

    -Scott

    post-415-125916729516_thumb.png

  12. The fourth byte (54) shows the type, but according to the documentation 0x54 is a waveform type. So I went ahead and wired up a waveform and I also get 0x54. Is this a bug? The two data types appear to not be equivalent (you can't wire up a waveform to a timestamp terminal, for example). Is there a way to differentiate between a waveform and a timestamp when using a variant?

    You need to look at the next I16 value after the base type. 0x03 is a waveform; 0x06 is a timestamp. The current version of OpenG LVData/Variant tools don't catch this. But the NI tools (...\LabVIEW xx\vi.lib\Utility\VariantDataType\...) will catch it.

  13. What if you want to strip a path that doesn't exist because it's gonna be a directory that will be created later? I think in this scenario, I want the strip path to work as a string parser. Now I understand that different OS have different ways of writing down a filepath and that's what I'd expect the Strip Path primitive to do, while strings are strings on any OS.

    That's what it does. The path doesn't have to exist for strip path to work. It will give you the stripped path and the stripped name. I haven't had any problems with this.

    I think the issue is what it should do with \\server\share UNC name. Rolf explained the technical details. It may not be what you expect, but it is consistent. The nomenclature \\server\share is similar to a drive letter (i.e. X:\). If you try to strip past X:\, you'll get X in the name an empty stripped path, the same as you get for \\server\share.

    -Scott

×
×
  • Create New...

Important Information

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