Sign in to follow this  
Followers 0
jsmcpn

Having trouble with $CmdLine when parsing an arg with spaces and special chars

5 posts in this topic

#1 ·  Posted (edited)

Hello all!  I'm trying to make a little script that sends a message over TCP.  An example payload would be:

MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>

Note how the payload contains special characters, and how the CDATA contains a SPACE (i.e.  "Not Running")

My compiled AU3 script expects exactly two command line arguments:

1) destination server/port expressed as 127.0.0.1:80

2) the payload I want to send to my server application (which may have multiple ATTRs, this example only has one ATTR)

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

 

My problems (plural) are with parsing of the second argument:

1)  If I don't wrap second argument in double-quotes, then Windows bails out before even launching EXE with "< was unexpected at this time"

2)  If I DO wrap second argument in double-quotes, then two problems can arise when my EXE parses the arguments:

             aa) The double-quotes are stripped from the CDATA value. ["Running"] is stored in the array as [Running]

             bb) If CDATA value DOES have a space, such as ["Not Running"], then I get an extra unwanted $CmdLine[3] because the SPACE between Not and Running is treated as a separator.  My second argument is thus split into two separate arguments, [2] and [3] instead of being treated as one arg stored in [2]

                        cc) Additionally, my script exits because it has an "IF $CmdLine[0] <>2 THEN Exit (1)" to validate the command line args.

I've tried launching the EXE with the second argument wrapped and escaped in a multitude of ways.  Double double-quotes, triple double-quotes, single-quotes on the outside with double-quotes inside (i.e.  '"ETC"'), starting the second arg with a caret (i.e. ^"ETC") and one of three things happens:

1) "< was unexpected at this time"

2) my CDATA value is stripped of its double-quotes

3) my payload argument gets split at the space in the CDATA value and the script bails out due to the unexpected 3rd argument.

 

Any ideas?  How can I preserve the second argument literally, including all special characters, quotes and spaces?

I tried adding some string manipulation code to grab the 2nd argument from $CmdLineRaw and it works (preserves the "Not Running" with quotes), but my number of arguments is still 3 instead of 2 if there is a space in the CDATA value.

 

Any assistance would be greatly appreciated!

Edited by jsmcpn

Share this post


Link to post
Share on other sites



Use $CmdLineRaw to get the whole parameter as a string and parse it yourself instead of letting the interpreter do it for you. Or use double quotes around the parameters that contain spaces.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

I thought $CmdLineRaw was probably the answer... BUT:

How do I validate that the script is run with exactly 2 arguments if the 2nd one gets split sometimes?  I can't trust $CmdLines[0] since it will be wrong if [2] has any spaces.

 

Thanks!

Share this post


Link to post
Share on other sites

When I use the parameters like this they don't lose the double quotes around Not Running.

127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

 It shows in $CmdLineRaw like this.

127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

Here's the program I wrote to display it in the console window when it's run compiled.

#AutoIt3Wrapper_Change2CUI=y
#include <Array.au3>
_ArrayDisplay($cmdline)
ConsoleWrite($cmdlineraw & @CRLF)

Compile this, start the compiled program with the command line parameters as shown above and you'll see that it's not stripping the quotes inside the second parameter when displaying the $CmdLineRaw line. Parsing the string should be relatively easy from there.

Validating that it's run with 2 parameters would be a little harder, but I'm sure someone can come up with a RegEx answer to validate that criteria.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

If the payload can contain absolutely any string of characters, then the problem remains somewhat complex. If, on the other hand, there exists some reasonably short string that will never appear in the payload, then you could use that string as a proxy for embedded double-quotes and wrap the entire argument in actual double-quotes. The argument count can then be checked, and your script would substitute a double-quote for each appearance of the proxy string.

E.g., if a run of three at-signs (@) can't appear in the payload, you could use that to replace the embedded double-quotes. In your example

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

would become

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA[@@@Not Running@@@]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

and your script could use

StringReplace($CmdLine[2], "@@@", '"')

to do the substitution.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • StMaSi
      By StMaSi
      If I am using a RunWait command to launch a batch file from within an AutoIt script, how can I pass a variable to said batch file so that the batch file can utilize said variable like in a %var% format? Thank you in advance.
    • AnonymousX
      By AnonymousX
      Hi,
      I'm trying to create a program where the user can input a material number into a GUI and the script will search out and find the respected material folder. I've been able to piece together the file mapping part so that the correct folder is stored within a variable. However I can not seem to get the Run function to work as the directory contains commas. Could I please get assistance with this?
      Here is some test code I've experimented with
      $filepath = "C:\Users\annoymousx\Documents\" ; Variable Works ;$filepath = "C:\Users\annoymousx\Documents\Test with Spaces\"; Works with folder spacing $filepath = $filepath & "Test with Spaces\"; Works with using a prior directory history $filepath = $filepath & "Folder with ()"; Works if brackets are used ;$filepath = $filepath & "\Folder with ," ;Does not Work if comma is used in file directory $filepath = $filepath & "\Folder with " & ""","""; Works if triple brackets are used Run("explorer.exe " & $filepath)  
      So I've learnt if you put triple quotations around a comma it will work correctly. The challenge is, in the actual script i'm not manually entering in text.
      Example:
      $filepath = $filepath & $Materialclass[$classnum] & "\"  
      Which is put into a loop, then at the end of the script I have the correct file path saved to the variable but it may contain many commas. 
      How would I take this variable with the correct file path and open windows explore to it?
      Say if the variable contained the value: C:\Users\anonymousx\Documents\This folder has a ,\comma, (comma, comma,)\And more , here
      Thanks for any suggestions,
       
    • MuffinMan
      By MuffinMan
      I am trying to rebuild an old single signon script that has been giving us a bit of trouble lately.  I didn't write it and it was written in another script language.  If the target program is already open it will have the current user's last name as part of the window text, which I am trying to compare against the user name to see if I should just WinActivate or Process Close and start the program over.  I will be provided the username like "jones", or "smith" and the title check works fine for last names (with no spaces), but if the last name DOES contains spaces, say "Nom De Plume", then all I will be given as a username is "nomdeplume".  Is there any way (via a regex maybe) that I can still check the text on the screen and somehow ?  I have been reading about the Advanced (4) mode of WinTitleMatchMode, but it is over my head.  Any help is appreciated.  Here is a small reproducer script:
      Opt("WinTitleMatchMode", -1) Run("Notepad") WinWait("[CLASS:Notepad]", "", 10) Send ("Smith" & @CRLF & "Jones" & @CRLF & "Nom De Plume" & @CRLF) If WinExists("[CLASS:Notepad]", "jones") Then MsgBox(0,"FOUND","Found Jones") EndIf If WinExists("[CLASS:Notepad]", "nomdeplume") Then MsgBox(0,"FOUND","Found Nom De Plume") EndIf  
    • david1337
      By david1337
      Hey guys
      Can anyone help me explain this?
      $szFile = "test.htm" $szText = FileRead($szFile) $szText = StringReplace($szText, "hello", "ö") FileDelete($szFile) FileWrite($szFile,$szText) If the file "test.htm" has it's text changed into something containing non US characters, in this example "ö", the output is " ö " when shown in a browser.
      If i manually change the text in the "test.htm" file to "ö" - the output in the browser is "ö" !
      In both cases, if the htm file is opened in notepad, the content is just "ö" - but the one changed from the script, still opens as " ö " in a browser. How weird is this?
      I am aware that I can replace the text to " &ouml;" , which is the HTML code for "ö" - then the output is correct in the browser, but this is just dumb when there are a lot of characters to be changed

      Does anyone know why this happens, and how to solve it in a more simple way?
       
    • ur
      By ur
      I need to write a code in which I am reading a text file which is of .vbs format and in that a line contains function signature like below
      Function CreateEnvironmentVariable($sType, $sName, $sValue, $bOverwrite)
      If the string is in above format, then I need to check number of arguments in it.
      For in above case it should return 4.
      Can anyone help me on this.