Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

MessageKey for missing library dialog

2012-09-25
2024-01-26
  • Frank Jepsen - 2012-09-25

    Hi,

    I am trying to open a project using ScriptEngine and report an error if the needed libraries does not exist in the current CoDeSys installation.

    My problem is that after running the open cmd, a dialog appears that I have to "click OK" at. I know from others topics here in forum, that some dialogs can be auto-answered using system.prompt_answers, but I do not know the MessageKey for the specific dialog.

    Information on dialog:
    Title: CoDeSys
    Text: One or more library references in this project faild to load. Please take a look in the messages view for further details.
    Buttons: OK

    Script used to bring up dialog, when myProject.project uses libraries that is not installed in current CoDeSys:

    proj = projects.open("myProject.project");
    system.prompt_answers["?WhichStringToWrite?"] = PromptResult.OK;
    

    Does someone know the MessageKey of this specific dialog?

    An alternative solution could be the one written prior on this forum by M.Schaber:

    M.Schaber hat geschrieben:
    In CoDeSys V3.5 SP1, the situation will improve a little bit. It will be possible to generically handle all simple MessageService prompts (those which only have a single OK button,
    thus giving no real "choice" to the user) by just logging them instead of triggering a popup.

    If someone has an example on how to do this logging of simple dialogs it would be really helpful.

    Best regards,
    Frank

     
  • Frank Jepsen - 2012-09-25

    I found the answer to alternative solution myself.

    For other users I can give an example that will make some dialogs go away:

    system.prompt_handling = PromptHandling.None
    
     
  • Anonymous - 2012-09-28

    Originally created by: M.Schaber

    Hi, Frank,

    I'm glad that you found the solution yourself.

    The secret is in the PromptHandling enum, which is a Bunch of Flags that you can combine. Here are the enum members:

          /// <summary>
          /// None of the flags are set. This implies that "simple" prompts are silently suppressed.
          /// </summary>
          [ReleasedEnumMember]
          None = 0,
          /// <summary>
          /// Handle simple prompts in their original way. Usually, this means, the user is queried with a dialog box.
          /// (However, other plugins may modify that behaviour.) This flag is 
          /// set by default in UI mode. If you disable this flag, simple promts are not processed in any way.
          /// </summary>
          [ReleasedEnumMember]
          ForwardSimplePrompts = 1 << 0,
          /// <summary>
          /// Print simple prompts as a log message, similar to <see cref="ISystem.write_message"/>.
          /// Log the prompts to the message view with appropriate priority. This is set by default in
          /// Non-UI mode.
          /// </summary>
          [ReleasedEnumMember]
          LogSimplePrompts = 1 << 1,
          /// <summary>
          /// Enables a basic text mode message service implementation in --noUI mode. By default,
          /// this flag is not set for compatibility reasons with old scripts, and it is ignored if
          /// <see cref="ISystem.ui_present"/> is true.
          /// </summary>
          /// <remarks>If this flag is not set, all MessageServicePrompts which ought to query the
          /// user simply return the default value, while <see cref="IScriptUI.open_file_dialog"/>,
          /// <see cref="IScriptUI.save_file_dialog"/>, <see
          /// cref="IScriptUI.browse_directory_dialog"/>, <see cref="IScriptUI.query_string"/>, <see
          /// cref="IScriptUI.query_password"/> and <see cref="IScriptUI.query_credentials"/> simply
          /// pop up the standard graphical dialogs.</remarks>
          [ReleasedEnumMember]
          EnableTextPrompts = 1 << 2,
          /// <summary>
          /// If this flag is set, prompts issued by the Script itself via <see
          /// cref="ISystem2.ui"/> are also subject to the <see cref="ISystem2.prompt_handling"/>
          /// and <see cref="ISystem.prompt_answers"/> processing / filtering. This flag is not set by
          /// default.
          /// </summary>
          [ReleasedEnumMember]
          ProcessScriptPrompts = 1 << 3,
          /// <summary>
          /// Logs all MessageService calls with their message key to the message store. Use this to
          /// catch the message keys you need for <see cref="ISystem.prompt_answers"/>.
          /// </summary>
          /// <remarks>Calls without a message key are logged with the key "&lt;&lt;No Key&gt;&gt;", calls
          /// which got passed None as message key are logged with "&lt;&lt;None&gt;&gt;"</remarks>
          LogMessageKeys = 1 << 4,
    

    The members marked with [ReleasedEnumMember] are present in V3.5 SP1, the LogMessageKeys is scheduled for V3.5 SP2.

    So if you want the simple prompts just to be logged to the message view (or console in --noUI-Mode), just set prompt_handling to PromptHandling.LogSimplePrompts (or any combination of flags which includes LogSimplePrompts and does not include ForwardSimplePrompts).

    To find out the message keys, simply add the "LogMessageKeys" flag to whatever flag combination you want to use normally:

    system.prompt_handling |= PromptHandling.LogMessageKeys
    

    Then, all MessageService prompts with their MessageKey are logged to the message view (or console in --noUI-Mode).

    HTH,
    Markus

     
  • Frank Jepsen - 2012-09-28

    Hi Markus,

    Thanks for the answer. I will be looking forward to see the LogMessageKeys functionality in SP2 - it sounds like a good solution.

    Best regards,
    Frank

     
  • Infusion - 2015-02-18

    Hello,

    (V3.5 SP5 Patch2)
    i already tried to get the message Keys, it is not working well,
    but perhaps there is a bug in my code.

    In the commands i am Searching for "Search" and then i am executing the command.
    After that the "Search" GUI shows up.

    My Problem is that i want to see the Message Keys of the "Search" GUI/Prompt in the Message Window.
    But there is no message in the message Window.
    Do i have to call and write the messages to the message window by myself ?

    Here is my Code:

    system.prompt_handling |= PromptHandling.LogMessageKeys

    for command in system.commands:
    if command.name == "Suchen":
    system.write_message(Severity.Information, "Kommando: " + command.name)
    if command.tokens[0] == "edit":
    print("Das ist das richtige")
    command.execute()

     
  • mkeller - 2015-02-18

    Hi Infusion.

    Infusion hat geschrieben:
    i already tried to get the message Keys, it is not working well,
    but perhaps there is a bug in my code.
    In the commands i am Searching for "Search" and then i am executing the command.
    After that the "Search" GUI shows up.
    My Problem is that i want to see the Message Keys of the "Search" GUI/Prompt in the Message Window.
    But there is no message in the message Window.
    Do i have to call and write the messages to the message window by myself ?

    The "Search" GUI is not generated by the IMessageService and therefore has no message key.

    The messages/dialogs of the IMessageService are used instead of the standard message boxes because they can be handled non-interactive. The CODESYS Test Manager, for example, use this feature to execute commands and handle the occurring messages according to its configuration.

    BR
    Martin

     
    • kevin123 - 2024-01-26

      Hi Martin,

      I got the messagekey of the "upgrade format warning dialog" with key:"<< No Key>>". (please refer to the attachment)

      Is that means i can't use

      system.prompt_answers["<<No Key>>"] = PromptResult.OK;
      

      to auto-answer 'OK' in this dialog?
      Is there any other way to auto-answer this dialog?
      Thanks!

       

      Last edit: kevin123 2024-01-26
  • Infusion - 2015-02-18

    Thank you for your answer.

    Is there a possibility to edit the "Search" GUI with the python script ?

    Because i have to find text passages with regular expressions, but perhaps there is another way to finish my task.

     
  • mkeller - 2015-02-18

    Hi Infusion.

    I think I misunderstood you. You want to use the "Find" command to find some text and not the "Search" command to open the online help.

    The Find & Replace commands don't have a non-interactive mode.

    What do you want to find? Maybe there is an other way.

    BR
    Martin

     
  • Infusion - 2015-02-18

    In my Projekt there are a lot of "unique" error function calls.

    Somethin like this :

    ErrorManager(ID,"Waht is wrong message",E_BEHAVIOR)

    ErrorManager(001,"No Signal from Sensor_1",E_STOP)
    ErrorManager(002,"No Signal from Sensor_2",E_HARD_STOP)

    And there are really a lot of this calls ~400.

    The IDs have to be unique, so when i want to include a new ErrorManager call (let's say for sensor_3),
    then i first have to find the highest number which is used as ID.

     
  • mkeller - 2015-02-18

    Hi Infusion.

    Are the calls inside the imported POUs? If yes, you can search in the XML file and modify the relevate code parts there.

    If not, then you can
    - export the POU and search there
    - walk through the object tree and use the new API for POU objects with textual declaration and/or implementation (V3.5 SP6 or newer)

    BR
    Martin

     
  • Infusion - 2015-02-19

    The export of the PLCOpenXML as String and File is working.

    But i have a problem with both of the exports.

    Situation:
    - numbers (FB) [1 2 3 4]
    - add (methode) [5 6]
    - substract (methode) [7 8]

    Problem: Searching Numbers

    With the string: "strXMLFile = treeobject.export_xml(exportReporter,'',False)"
    advantage : no external temporary file
    disantvantages:
    - when i export the XML of an object of the methodes, then the code content of the overlaying FB is also present in the XML
    - when i want to convert the ixportet string into python (import xml.etree.ElementTree as ET --> tree = ET.fromstring(strXMLFile)) that is not possible

    With the file: "treeobject.export_native(filename, False)"
    advantage : perhaps that it is working more or less
    disadvantages:
    - temporary files
    - every row of the ST Code is written in an extra XML row, so the searching process (regular expression) is verry difficult

    Waht i found in the exportet PLCopenXML files is: "treeobject.export_xml(exportReporter,filename,False)"
    <pou name="Zahlen" poutype="functionBlock">
    <method name="ZahlHinzufuegen"></method></pou>

    so it would be possible to differ between the needed information.

    Is it possible to rebuild a XML tree in python from any export_YXZ methode output ?

     
  • Anonymous - 2015-03-02

    Originally created by: M.Schaber

    Just some remarks:

    • As far as I know, Methods cannot exist without the defining POUs in PLCOpenXML. Thus, when exporting, the method always comes with the POU.

    • In V3.6 SP6, we did add new methods to directly access of textual declaration and implementation parts of POUs, GVL, Method, etc...

    • What exact error are you getting when you try to create an element tree from the xml file? And which CODESYS version are you using?

     
  • Infusion - 2015-03-11

    Hello,

    I am using the V3.5 SP5 Patch 2+.

    There was an other Error Message before, which only said that theere is a wrong/not xml conform sign in the xml export string.
    Perhaps i can try to get the "old" error message again.

    IMG: XML_Element_Tree_Error.JPG

     
  • mkeller - 2015-03-11

    Hi Infusion.

    Was your PLCopenXML file created by CODESYS or with .Net? If yes, then the file contains the BOM (Byte Order Mark) which other XML parser don't expect. You have to skip the first 3 bytes of the file before the real XML content starts.

    Here is my implementation for python:

    xmlfile = io.open('c:\\Temp\\devices.xml', 'r')
    xmlfile.seek(3)
    tree = ET.parse(xmlfile)
    xmlfile.close()
    

    BR
    Martin

     
  • Infusion - 2015-03-11

    I just found the failure myself

    IMG: XML_String_Error_2.JPG

     

Log in to post a comment.