Sign in to follow this  
Followers 0
GO7

Command, Spaces and Redirection... Again!

13 posts in this topic

Hi!

i know this has been asked multiple times on this forum, but i've tried everything, read tens of topics and still I can't manage to launch a dos command.

Here is the problem : i want to run a program from the command line and redirect the output to a file.

If I type C:\path\to\my_program.exe > D:\path\to\my_file.txt in cmd.exe, it works all right. The problem is that the path may contain spaces. In cmd, you just need to put double quotes(") like this : "C:\path with spaces\to\my_program.exe" > "D:\path with spaces\to\my_file.txt"

Now i want to do this from an autoit script. So I wrote :

RunWait(@ComSpec & ' /c "' & $exe & '" > "' & $res & '"', "", @SW_HIDE)oÝ÷ Ø­¡÷(º»Ú²}ý·
+ýË«zØ^Â%zËkx"±Ê+­ç-ëvk nZ×%n¶Ú-zËm«l¢-ý«,ºh§+wöË(ëax-¡Ú0Ø×±z¶­êí©ÚºÚ"´ý½ëkçm¢ëªê-ªê-ªê-ªê-{-y§hjºjºwôý½æ¥²¬yÛ-®)àæjÖ®¶­sbb33c¶6öÖÖæBÒ7G&ætf÷&ÖBb33²W2ö²gV÷C²W2gV÷C²fwC²gV÷C²W2gV÷C²b33²Â6öÕ7V2Âb33c¶WRÂb33c·&W2

and tons of other things...

A strange thing is that without the redirection, it works fine. As soon as i add the redirection, i get the following error in the command window (if i change /c to /k and delete @SW_HIDE) : The filename, directory name, or volume label syntax is incorrect.

I'm kind of desperate ! Can you help me ?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

If you want to replicate the problem, you can try the following script:

$exe =  @ScriptDir & "\ip config.exe"
$res = @ScriptDir & "\output with spaces.txt"

FileCopy(@SystemDir & "\ipconfig.exe", $exe)

;This should work
$command = @ComSpec & ' /k "' & $exe & '"'
MsgBox(0, "", $command)

Run($command)

;This won't
$command = @ComSpec & ' /k "' & $exe & '" > "' & $res & '"'
MsgBox(0, "", $command)

Run($command)

As you can see, it will copy ipconfig from the system dir to the scriptdir, add a space to the executable name and launch the command with cmd.exe

The first run sould work and display the usual result of ipconfig.exe

For the second run, the msgbox shows that the line is OK, but you should get an error in the command window :

'D:\My_Programs\AutoItv3\Scripts\prototypes\ip' is not recognized as an internal

or external command,

operable program or batch file.

Edited by GO7

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I'm not really sure why it doesn't work, maybe has something to do with that you use " " and then " " again in the script, anyways, this worked for me:

#include <file.au3>

_FileCreate(@ScriptDir & "\output with spaces.txt")

$exe =  FileGetShortName(@ScriptDir & "\ip config.exe")
$res = FileGetShortName(@ScriptDir & "\output with spaces.txt")

FileCopy(@SystemDir & "\ipconfig.exe", $exe)

$command = @ComSpec & ' /k "' & $exe & ' > ' & $res & '"'
MsgBox(0, "", $command)

Run($command)

Basically, I changed the '" > "' into ' > ', and used short file names instead... dos can be a bitch lol

Edit:

The _FileCreate() is necessary because otherwise the FileGetShortName() function fails, and returns the full (original) path..

Edited by FreeFry

Share this post


Link to post
Share on other sites

dos can be a bitch

That's the conclusion i also came to :)

It seems that you can only have spaces in either $exe or $res.

I've found 2 other workaround :

  • do not use " > " but instead StdoutRead
  • set the working dir of Run() to either $exe dir or $res dir
Your solution also works !

Share this post


Link to post
Share on other sites

Wouldn't it be more like:

$command = @ComSpec & ' /k "' & $exe & '" > "' & $res & '"'
?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Wouldn't it be more like:
$command = @ComSpec & ' /k "' & $exe & '" > "' & $res & '"'

also: double-quotes aren't needed anymore in $command...

Share this post


Link to post
Share on other sites

Ah yes, my mistake sorry. :)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

That's the original code i tried and no it doesn't work !

but there is a small mistake in FreeFry code : in order for FileGetShortName to work, the file must already exist (that why he used filecreate). So $exe should exist before calling FileGetShortName

#include <file.au3>

$exe =  @ScriptDir & "\ip config.exe"
$res = @ScriptDir & "\output with spaces.txt"

FileCopy(@SystemDir & "\ipconfig.exe", $exe)
_FileCreate($res)

$exe =  FileGetShortName($exe)
$res = FileGetShortName($res)

$command = @ComSpec & ' /k ' & $exe & ' > ' & $res
MsgBox(0, "", $command)

Run($command)oÝ÷ Ù©l¡Ú.nWªº^±ªÞmçyÖ§Êj+z)ôߧ(f§wú®¢×¢ºò#¬~e£§Ø^­ëâ²*'~º&¶¥jËi¢ËHßÛÞ¥êì¢v¥)Þ½êáiÖ§Ë.zë"h¹¹^ªê-zƧv)ßiËfÈX¥x¸¬µ:®¶²¬zËazƦzg­r¢ì­ê+§jYr¶¼¢hºÇØ­Âä±ø§xw«z+l,¶­¢ë_W¡ë'ßÛaj÷­¡·­æ­y×â®ËGz·¢±«'^µúèX¥x¸¬µ:®¶²®¶­sbb33c·5DföÆFW"Òb33c¶ôe4òävWE7V6ÄföÆFW""¢Æö6Âb33c¶÷WDfÆRÒFV×F"fײb33c¶ôe4òävWEFV×æÖP¢bæ÷B7G&ætå7G"b33c·4fÇFW"Âb33³²b33²FVâb33c·4fÇFW"f׳Òb33³²b33°¢Æö6Âb33c¶7ÆBÒ7G&æu7ÆB7G&æu7G&u2b33c·4fÇFW"ÂÂb33³²b33²Âb33c·5&V@¢f÷"b33c¶42ÒFòb33c¶7ÆE³Ð¢b7G&æu7G&u2b33c¶7ÆE²b33c¶45ÒÂÒb33²b33²FVâ6öçFçVTÆö÷¢b7G&ætÆVgBb33c¶7ÆE²b33c¶45ÒÂÒb33²âb33²æBð¢T&÷VæB7G&æu7ÆBb33c¶7ÆE²b33c¶45ÒÂb33²âb33²Ò"ÒFVâb33c¶7ÆE²b33c¶45ÒÒb33²¢b33²fײb33c¶7ÆE²b33c¶45Т'VåvB6öÕ7V2fײb33²ö2b33²fײb33¶F"gV÷C²b33²fײb33c·5Ffײb33²b3#²b33²fײb33c¶7ÆE²b33c¶45Òð¢fײb33²gV÷C²ö"öòÖRööBfwC²gV÷C²b33²fײb33c¶÷WDfÆRfײb33²gV÷C²b33²Âb33²b33²Â5uôDR¢b33c·5&VBf׳ÒfÆU&VBb33c¶÷WDfÆR·&V7W'6fVÇ7F÷&R6ÖBæWR÷WGW@¢bæ÷BfÆTW7G2b33c¶÷WDfÆRFVâ&WGW&â6WDW'&÷"BÂBÂb33²b33²´b6ÖBæWRFFâb33·B7&VFRFRfÆRÂFVâ&WGW&à¢fÆTFVÆWFRb33c¶÷WDfÆR´FVÆWFRfÆRæB6öçFçVRÆö÷¢æW

1. I get a temp name

2. I use "RunWait" so I don't go any further until it is done logging

You see that cmd.exe is actually creating the file itself, and I'm deleting it after storing the information read from the file... because I'm looping it, I'm storing it recursively with &=.

Maybe it helps, maybe it doesn't.... but I saw the iteration made on having to use short names and having to have the file created first, I'd just thought I'd show you that you really don't have too (Proof in the pudding so to speak).

Edit:

I should also state, I've never tried to go from one hard drive to another... so maybe you do in fact have to have it created and use short names, there's no way for me to test that though.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

have you tried the code in my second post ? On my computers, it doesn't work... And it's indeed what you do in your script...

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

have you tried the code in my second post ? On my computers, it doesn't work... And it's indeed what you do in your script...

Yes... I don't understand myself:

This one is basically how you have yours set up now, and it works.

$exe =  @ScriptDir & "\ip config.exe"
$res = @ScriptDir & "\output with spaces.txt"

If FileExists($exe) = 0 Then FileCopy(@SystemDir & "\ipconfig.exe", $exe)
FileClose(FileOpen($res, 2))
$exe =  FileGetShortName(@ScriptDir & "\ip config.exe")
$res = FileGetShortName(@ScriptDir & "\output with spaces.txt")

RunWait(@ComSpec & ' /c ' & $exe & ' > ' & $res, '', @SW_HIDE)oÝ÷ Ù8b²Þ©³Mú{¿Ó~«zË!¢»gjg¬mçè­ç+y«b¢{ayø¥zÆ«yÊÞj×në]¡ë'ßÛp¢¹-+(èZ²g¬¶é©y×è®Ë«y«­¢+Ø(ÀÌØíáô¥±ÑM¡½ÉÑ9µ¡MÉ¥ÁѥȵÀìÅÕ½ÐìÀäÈí¥À½¹¥¹áÅÕ½Ðì¤(ÀÌØíÉÌô¥±ÑM¡½ÉÑ9µ¡MÉ¥ÁѥȵÀìÅÕ½ÐìÀäÈí½ÕÑÁÕÐÝ¥Ñ ÍÁ̹ÑáÐÅÕ½Ðì¤()%¥±á¥ÍÑÌ ÀÌØíá¤ôÀQ¡¸¥±
½Áä¡MåÍѵ¥ÈµÀìÅÕ½ÐìÀäÈí¥Á½¹¥¹áÅÕ½Ðì°ÀÌØíá¤)¥±
±½Í¡¥±=Á¸ ÀÌØíḚ́Ȥ¤()IÕ¹]¥Ð¡
½µMÁµÀìÌäì½ÌäìµÀìÀÌØíáµÀìÌäìÐìÌäìµÀìÀÌØíÉÌ°ÌäìÌäì°M]}!%oÝ÷ Ù8b²ÞËazƦy«nÞnëH¶.fk&Þܱ·¢§µêé­ë^uØ}êÞÙrv÷öÙ'£!ÊʺÇvꮢ׬jwbµØmÂäjëh×6
$exe =  FileGetShortName(@ScriptDir & "\ip config.exe")
$res = FileGetShortName(@ScriptDir & "\output with spaces.txt")

If FileExists($exe) = 0 Then FileCopy(@SystemDir & "\ipconfig.exe", $exe)
FileClose(FileOpen($res, 2))

RunWait(@ComSpec & ' /c "' & $exe & '" > "' & $res & '"', '', @SW_HIDE)

Then for giggles I repeated the above with ShellExecute(@SystemDir & '\cmd.exe', etc...) the results were the same as above....

Sorry for doubting...

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Go7,

It's definitely a Windows related thing, 'cause if you do ClipPut your original command and then try running that from the Windows "Start|Run" command, you get the same error.

I did a lot of testing and discovered that wrapping the whole $exe & $res in double quotes will also work:

$exe =  @ScriptDir & "\ip config.exe"
$res = @ScriptDir & "\output with spaces.txt"

FileCopy(@SystemDir & "\ipconfig.exe", $exe)

$command = @ComSpec & ' /k ""' &  $exe & '" > "' & $res & '""'

MsgBox(0, "", $command)

Run($command)

So note that after comspec you need double double quotes to open and double double quotes to close after $res

Weird behaviour, definitely easier to use the GetShortFileName options to keep things clear, but thought you'd want to know.

Share this post


Link to post
Share on other sites

Wow :) ! Thanks a million ! So apparently everything after cmd.exe must be surrounded by double quotes...

I read the help on cmd and i find this interesting paragraph :

CODE
If /C or /K is specified, then the remainder of the command line after

the switch is processed as a command line, where the following logic is

used to process quote (") characters:

1. If all of the following conditions are met, then quote characters

on the command line are preserved:

- no /S switch

- exactly two quote characters

- no special characters between the two quote characters,

where special is one of: &<>()@^|

- there are one or more whitespace characters between the

the two quote characters

- the string between the two quote characters is the name

of an executable file.

2. Otherwise, old behavior is to see if the first character is

a quote character and if so, strip the leading character and

remove the last quote character on the command line, preserving

any text after the last quote character.

So I suppose that in the previous examples, the first double quotes were stripped leading to the error message

'D:\My_Programs\AutoItv3\Scripts\prototypes\ip' is not recognized as an internal or external command, operable program or batch file.

Weird...

Anyway, thanks again for solving this big mystery !

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