11 Replies Latest reply on Feb 27, 2009 10:53 AM by escouten

    Problem with & character

    (Kamal_Sharif)
      Hello;
      I posted a thread named "A bug in LrXml" a while a go and unfortunatly, no one has had any comment so far. Today, I found out that the problem may not be specifically with LrXml! I am having trouble displaying the & in any UI controls.
      I even tried string.char(38) and still get a blank string. The string is not blank as you may ask for the lenght and it is there, it just not showing it.
      Has anyone ever had to deal with this or am I missing something? Probably I am stepping over a special case and not noticing it.
      For example:
      local s='Black&White'
      LrDialogs.message("Display s",s,'info')

      and what you see on the screen is BlackWhite and if you call string.len(s), it reaturns 11 which means the ampersand is there.

      Thanks
      Kamal
        • 1. Re: Problem with & character
          escouten Adobe Employee
          AH HA!<br /><br /><light bulb goes off><br /><br />Is this on Windows?<br /><br />Windows, by default, strips the ampersand character from most (all?) control titles. In Windows-speak, the ampersand means that the following character is an accelerator.<br /><br />Try substituting a double-&& where the single & exists in the string. In other words ...<br /><br />local s='Black&&White'<br />LrDialogs.message("Display s",s,'info')
          • 2. Re: Problem with & character
            (Kamal_Sharif) Level 1
            Hello Erick;
            Thanks for the note. That explained part of the issue. I can now display the ampersand on the screen, but no in the actual place I want. I am, basically, passing a string like C:\Program Files\blabla\Black&White\run.exe to LrTasks.execute and it never gets run.
            I am spitting out the command to a log file and it seems the right path. What I am currently doing as a work around is having a small java program that gets a commmand line argument and runs that in shell. The java bridge works, but I would like to remove as much garbage as possible.
            Thanks
            • 3. Re: Problem with & character
              escouten Adobe Employee
              I suspect your problem is that you need to escape the space in C:\Program Files\...
              • 4. Re: Problem with & character
                (Kamal_Sharif) Level 1
                Actually, I am putting the whole string in "", so I doubt the problem can be space.
                if(WIN_ENV==true)then
                cmd=string.format('"%s"',jar,execPath)
                local r,msg=LrTasks.execute( cmd )
                Logger.log(cmd)
                Logger.logf("Done launching DS, ret was %d", r)
                Logger.logf("reason, %s", msg)
                end

                The logger sends "C:\Program Files\....\somefile.exe"; which means I should be fine there. However, I think someting may be going on under the hood with LrTasks implemenatio when it tries to get the command string passed to it.
                • 5. Re: Problem with & character
                  escouten Adobe Employee
                  This is getting to be quite the walk in the wilderness, isn't it?

                  To say that the Windows team chose some shell unusual escaping patterns would be a major exercise in understatement. Unfortunately, cmd.exe doesn't respond to quotes around the path name when you pass it in through the OS. The interactive shell behaves differently than the underlying OS call.

                  In this case, you need to replace space with up-arrow+space ("^ "). Why? Who knows ...

                  The following code is excerpted from the site where Lightroom calls out for post-processing actions:

                  local function shellEscape_str( param, escapeSpacesOnWin )

                  if WIN_ENV then

                  -- Windows cmd.exe has some truly goofy shell-escaping techniques. *sigh*

                  param = param:gsub( '%^', '^^' )
                  param = param:gsub( '&', '^&' )
                  param = param:gsub( '|', '^|' )
                  param = param:gsub( '%(', '^(' )
                  param = param:gsub( '%)', '^)' )
                  param = param:gsub( '<', '^<' )
                  param = param:gsub( '>', '^>' )

                  if param:find( ' ' ) then
                  if escapeSpacesOnWin then
                  param = param:gsub( ' ', '^ ' )
                  else
                  param = param:gsub( '"', '""' ) -- " (make Mac syntax colorizer happy)
                  param = string.format( '"%s"', param )
                  end
                  end

                  else

                  param = param:gsub( '\\', '\\\\' )
                  param = param:gsub( ' ', '\\ ' )
                  param = param:gsub( '%*', '\\*' )
                  param = param:gsub( '#', '\\#' )
                  param = param:gsub( '"', '\\"' )
                  param = param:gsub( "'", "\\'" )
                  param = param:gsub( '%$', '\\$' )
                  param = param:gsub( '|', '\\|' )
                  param = param:gsub( '&', '\\&' )
                  param = param:gsub( '%?', '\\?' )
                  param = param:gsub( ';', '\\;' )
                  param = param:gsub( '~', '\\~' )
                  param = param:gsub( '%(', '\\(' )
                  param = param:gsub( '%)', '\\)' )
                  param = param:gsub( '<', '\\<' )
                  param = param:gsub( '>', '\\>' )
                  param = param:gsub( '!', '\\!' )
                  param = param:gsub( '%^', '\\^' )

                  end

                  return param

                  end

                  This gets passed to LrTasks.execute (OK, our internal variant of that) with roughly the following sequence:

                  LrTasks.execute( "cmd /c " .. shellEscape_str( pathToApplication, true ) .. " " .. otherArgs )

                  -- otherArgs is formed by calling shellEscape_str( path, false ) on the file paths you want to pass to the app.

                  (This isn't the exact code, but a rough paraphrase of it.)
                  • 6. Re: Problem with & character
                    escouten Adobe Employee
                    BTW, the blue emoticon :( in the above code snippet is supposed to be percent, left-paren

                    : ( without the space
                    • 7. Re: Problem with & character
                      (Kamal_Sharif) Level 1
                      Thanks Erick. Lots of characters to watch out for.
                      :(

                      :-)
                      • 8. Re: Problem with & character
                        Level 1
                        Kamal -

                        I had incredible trouble trying to get LrTasks.execute to launch an app successfully, i.e. it never worked. Finally, the technique I used that succeeded was to use cmd.exe's "start" command. The shell escaping seems to be interpreted differently there. An added benefit of going this route is that even though Lightroom launches a hidden shell window, the start command launches a new one that lets you see command output that may be useful for debugging. If you want to hide this new window, just pass /B as an argument. Keep in mind that the "start" command is asynchronous so more than likely you'll need to also use the /WAIT option. You may also need to pass a dummy value for the window title that "start" expects. The command ends up looking like this for debug mode:

                        start /WAIT "dummy title" myapp.exe

                        and for non-debug mode:

                        start /B /WAIT "dummy title" myapp.exe

                        In my app, myapp.exe is actually a quoted string that looks like this, no need for funky escapes:

                        "c:\program files\imagemagick-6.4.2-q16\convert.exe"
                        • 9. Re: Problem with & character
                          (Kamal_Sharif) Level 1
                          Thanks Dave;
                          That is very interesting. I have only used start to open a file in its default application!
                          For my case here, I am launching a GUI application so some of the args does not apply, but still getting rid of the escaping is a big plus.

                          @Eric: your former post was very useful as it takes into account all the possibilities, not just &. Thanks.

                          Kamal
                          • 10. Re: Problem with & character
                            Level 1
                            Eric -

                            I wonder if it would be useful to expose the shellEscape function to the SDK so that we can all make use of consistent and correct escaping that Lr has already worked out. My hunch is that peoples' intuition with LrTasks.execute() on Windows is that arguments are being passed directly to CreateProcess and not within a shell as Lr does (i.e. prefixed by "cmd.exe /c"). That would mean that users' instincts for debugging escaping problems aren't quite accurate.

                            Dave
                            • 11. Re: Problem with & character
                              escouten Adobe Employee
                              Good suggestion, thanks.