Sign in to follow this  
Followers 0
Angel

Opening a file with spaces on the filename

20 posts in this topic

Hi,

this should be REALLY simple, but I cannot make it work!

I am trying to simply open a file, using its default program (for instance, excel for an .xls file). The file is in a folder that has white spaces on its filename.

This is what I tried:

RunWait(@ComSpec & ' /C start "c:\Documents and Settings\labuser\My Documents\test.xls"')

When I do this, a Command Prompt window is open, whose title is "c:\Documents and Settings\labuser\My Documents\test.xls", but the file is not open.

If I do the same thing for a file without spaces on its filename, the file opens without any problems.

As you see I am using quotes and single quotes to surround the filename. What I am doing wrong?

Thanks,

Angel

Share this post


Link to post
Share on other sites



I agree that it should be simple, but MS changed it and made it a trap for users.

Starts a separate window to run a specified program or command.

START ["title"] [/Dpath] [/MIN] [/MAX] [/sEPARATE | /SHARED]

[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]

[/WAIT] [command/program]

[parameters]

"title" Title to display in window title bar.

path Starting directory

The first set of quotes for OSes XP and above, is used for the window title so I would go along with Valuater's method to help avoid the trap.

:P

Share this post


Link to post
Share on other sites

Thanks a lot for the help guys. Valuater, the FileGetShortName trick was very clever! I am sure it will come handy quite often! :P

MHz, I had no clue that the "title" think existed in winxp and winnt. After googling a bit I found that on windows95/98 and Me it does not work that way. So this is my final solution, which I've tested and works great. I decided agains using the FileGetShortName trick because it gave the wrong title in some applications.

Func _RunFile($sFileName)
    If @OSTYPE = "WIN32_WINDOWS" Then
        ; Windows 95/98/ME use a slightly different format for the "start command"
        Run(@ComSpec & ' /c start "' & $sFileName & '"', "", @SW_HIDE)
    Else
        ; Newer versions of windows add a "Title" paramter to the "start command"
        ; This parameter is actually ignored when opening files
        Run(@ComSpec & ' /c start "Starting Program..." "' & $sFileName & '"', "", @SW_HIDE)
    EndIf
EndFunc   ;==>_RunFile

Actually, I think that this problem is probably common enough and useful enough that this merits being included in one of the default libraries. Probably in "Process.au3" where _RunDOS is now. What do you guys think? Should I ask JdeB about it?

Cheers,

Angel

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

what about this replacement of _RunDos() ?:

Func _RunDOS($sCommand, $Title = "AutoIt3 _RunDos")
    If @OSTYPE = "WIN32_WINDOWS" Then
        ; Windows 95/98/ME use a slightly different format for the "start command"
        Run(@ComSpec & ' /c start "' & $sCommand & '"', "", @SW_HIDE)
    Else
        ; Newer versions of windows add a "Title" parameter to the "start command"
        ; This parameter is actually ignored when opening files
        Run(@ComSpec & ' /c start "' & $Title & '" "' & $sCommand & '"', "", @SW_HIDE)
    EndIf
EndFunc   ;==>_RunDOS
Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

what about this replacement of _RunDos() ?:

Func _RunDOS($sCommand, $Title = "AutoIt3 _RunDos")
    If @OSTYPE = "WIN32_WINDOWS" Then
        ; Windows 95/98/ME use a slightly different format for the "start command"
        Run(@ComSpec & ' /c start "' & $sCommand & '"', "", @SW_HIDE)
    Else
        ; Newer versions of windows add a "Title" parameter to the "start command"
        ; This parameter is actually ignored when opening files
        Run(@ComSpec & ' /c start "' & $Title & '" "' & $sCommand & '"', "", @SW_HIDE)
    EndIf
EndFunc   ;==>_RunDOS

I removed the title parameter because in my tests I noticed that you actually never see the title (as you run the command window in @SW_HIDE mode and it exits immediatly anyway).

Also, I kept the RunWait in the default mode.

I like the fact that this gives a single function for opening or starting any program or file in autoit. We may even add a $bRunWait parameter to select between Run and RunWait. The only issue that I see is that _RunDOS seems a slightly weird name for what this function does, as you basically hide the DOS window and the user never really sees it. Any ideas on what this generic "generic run" function could be called instead?

Cheers,

Angel

Share this post


Link to post
Share on other sites

The only problems I see is that the current _RunDOS uses RunWait instead of Run, which would not work for opening files (you do not want to make the AutoIt program wait until you close the file) and that currently _RunDOS does not use "start" command.

Actually, do you guys know if there is some case if which calling start would not be advisable?

Alternativelly, if you think that it'd be better to use a single function, _RunDOS, what we could do is add a parameter that controls whether "start" must be used. To keep the current behavious of _RunDOS untouched, and avoid breaking current scripts, by default the start command would not be used. This would look as follows:

Func _RunDOS($sCommand, $bUseStartCommand = False)
  If $bUseStartCommand Then
    If @OSTYPE = "WIN32_WINDOWS" Then
        ; Windows 95/98/ME use a slightly different format for the "start command"
        Return Run(@ComSpec & ' /c start "' & $sCommand & '"', "", @SW_HIDE)
    Else
        ; Newer versions of windows add a "Title" parameter to the "start command"
        ; This parameter is actually ignored when opening files
        Return Run(@ComSpec & ' /c start "' & $Title & '" "' & $sCommand & '"', "", @SW_HIDE)
    EndIf
  Else
    ; Do not use the start command. This also waits for the program to complete
    Return RunWait(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
  EndIf
EndFunc   ;==>_RunDOS

I removed the title parameter because in my tests I noticed that you actually never see the title (as you run the command window in @SW_HIDE mode and it exits immediatly anyway).

Also, I kept the RunWait in the default mode.

I like the fact that this gives a single function for opening or starting any program or file in autoit. We may even add a $bRunWait parameter to select between Run and RunWait. The only issue that I see is that _RunDOS seems a slightly weird name for what this function does, as you basically hide the DOS window and the user never really sees it. Any ideas on what this generic "generic run" function could be called instead?

Cheers,

Angel

Think this is a good alternative for the current _RunDos()... just need to change the $title to a fixed text....

Will do some testing and change the current _RunDos() for this version.... (after changing the docs )

:P


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Think this is a good alternative for the current _RunDos()... just need to change the $title to a fixed text....

Will do some testing and change the current _RunDos() for this version.... (after changing the docs )

:P

Yeah, sorry, I forgot to change the reference to $title into a fixed text :">

If you are going ahead and changing the function, should we add an option to be able to force the use of RunWait or Run? I implemented this in the following version (which also fixed the title thing)

Func _RunDOS($sCommand, $bUseStartCommand = False, $bWaitMode = -1)
  Local $sFullCommand
  If $bUseStartCommand Then
    If @OSTYPE = "WIN32_WINDOWS" Then
      ; Windows 95/98/ME use a slightly different format for the "start command"
      $sFullCommand = @ComSpec & ' /c start "' & $sCommand & '"'
    Else
      ; Newer versions of windows add a "Title" parameter to the "start command"
      ; This parameter is actually ignored when opening files
      $sFullCommand = @ComSpec & ' /c start "AutoIt3 _RunDos" "' & $sCommand & '"'
    EndIf
    
    ; When using the "start command" by default DO NOT WAIT for the command to finish (i.e. use Run())
    If $bWaitMode = 1 Then
      ; If the user FORCED the WAIT, use RunWait()
      Return RunWait($sFullCommand, "", @SW_HIDE)
    Else
      ; In all other cases (DEFAULT and FORCE to NOT WAIT), call Run()
      Return Run($sFullCommand, "", @SW_HIDE)
    EndIf
  Else
    ; Do not use the "start command"
    ; In this case by default WAIT for the command to finish (i.e. use RunWait())
    If $bWaitMode = 0 Then
      ; If the user FORCED to NOT WAIT, use Run()
      Return Run($sCommand, "", @SW_HIDE)
    Else
      ; In all other cases (DEFAULT and FORCE to WAIT), call RunWait()
      Return RunWait(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
    EndIf
  EndIf
EndFunc   ;==>_RunDOS

Do you think this is overkill? I think that there may be a few instances when it would be handy to be able to select between Run() and RunWait(). I could probably have made this code even simpler if I had used "Eval" or "Call", but I think this code is better.

It is a pity that the latest stable AutoIt version is already out, though, as this will certainly be handy!

Cheers,

Angel

Share this post


Link to post
Share on other sites

If you do use RunWait with the Start command, then it may pay to look at using the Wait switch also?

RunWait(@ComSpec & ' /c Start /Wait "" "' & $command & '"', '', @SW_HIDE)

Share this post


Link to post
Share on other sites

If you do use RunWait with the Start command, then it may pay to look at using the Wait switch also?

RunWait(@ComSpec & ' /c Start /Wait "" "' & $command & '"', '', @SW_HIDE)
Actually, I just looked more carefully at the documentation for the start command and it says the following:

When executing an application that is a 32-bit GUI application, CMD.EXE

does not wait for the application to terminate before returning to

the command prompt. This new behavior does NOT occur if executing

within a command script.

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

Therefore, it makes no sense to distinguish between RunWait and Run in the case in which we execute the "start command". It could only be useful for the other case (as the current _RunDOS does). I would say that it is still useful to distinguish between Run() and RunWait() in that case. This means that there are 3 cases instead of 4 and thus we could simply have a single optional parameter called "$runMode":

[autoit]

Func _RunDOS($sCommand

Share this post


Link to post
Share on other sites

Actually, I just looked more carefully at the documentation for the start command and it says the following:

When executing an application that is a 32-bit GUI application, CMD.EXE

does not wait for the application to terminate before returning to

the command prompt. This new behavior does NOT occur if executing

within a command script.

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

Therefore, it makes no sense to distinguish between RunWait and Run in the case in which we execute the "start command". It could only be useful for the other case (as the current _RunDOS does). I would say that it is still useful to distinguish between Run() and RunWait() in that case. This means that there are 3 cases instead of 4 and thus we could simply have a single optional parameter called "$runMode":

[autoit]

Func _RunDOS($sCommand, $bRunMode = 1)

If $bRunMode = 1 Then

; This is the original mode for this function in which @ComSpec is called directly,

; without invoking the "start command" AND AutoIt WAITS for the command to finish

Return RunWait(@ComSpec & " /C " & $sCommand, "",

Share this post


Link to post
Share on other sites

If you do use RunWait with the Start command, then it may pay to look at using the Wait switch also?

RunWait(@ComSpec & ' /c Start /Wait "" "' & $command & '"', '', @SW_HIDE)
Actually, I just looked more carefully at the documentation for the start command and it says the following:

When executing an application that is a 32-bit GUI application, CMD.EXE

does not wait for the application to terminate before returning to

the command prompt. This new behavior does NOT occur if executing

within a command script.

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

Therefore, it makes no sense to distinguish between RunWait and Run in the case in which we execute the "start command". It could only be useful for the other case (as the current _RunDOS does). I would say that it is still useful to distinguish between Run() and RunWait() in that case. This means that there are 3 cases instead of 4 and thus we could simply have a single optional parameter called "$runMode":

[autoit]

Func _RunDOS($sCommand, $bRunMode = 1

Share this post


Link to post
Share on other sites

If you do use RunWait with the Start command, then it may pay to look at using the Wait switch also?

RunWait(@ComSpec & ' /c Start /Wait "" "' & $command & '"', '', @SW_HIDE)
Actually, I just looked more carefully at the documentation for the start command and it says the following:

When executing an application that is a 32-bit GUI application, CMD.EXE

does not wait for the application to terminate before returning to

the command prompt. This new behavior does NOT occur if executing

within a command script.

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

Therefore, it makes no sense to distinguish between RunWait and Run in the case in which we execute the "start command". It could only be useful for the other case (as the current _RunDOS does). I would say that it is still useful to distinguish between Run() and RunWait() in that case. This means that there are 3 cases instead of 4 and thus we could simply have a single optional parameter called "$runMode":

[autoit]

Func _RunDOS($sCommand

Share this post


Link to post
Share on other sites

Actually, I just looked more carefully at the documentation for the start command and it says the following:

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

CMD.exe does not wait at a command prompt which is opposite to a batch file command which does. But the reference is to CMD.exe and not the use of Start itself. Upon using Start /Wait, I get the prompt remaining, but key input is not available. The strange thing is the message pump still caches the input and returns the input when the application is closed and control returns.

$command = 'calc'
$pid = Run(@ComSpec & ' /c Start /Wait "Title" "' & $command & '"')
ProcessWaitClose($pid)

Oddly enough, If I use "Title" which seems as not working but calc runs with 1 command prompt window remaining open. If I remove "Title", then a second window opens with execution and "calc" becomes the title. Using the Start command seems very illogical to understand :P . Using XP Pro SP2 here.

Share this post


Link to post
Share on other sites

I was trying to reply earlier but for some reason the forum wouldn't let me send a new post. Here is what I wanted to say:

I just looked more carefully at the documentation for the start command and it says the following:

When executing an application that is a 32-bit GUI application, CMD.EXE

does not wait for the application to terminate before returning to

the command prompt. This new behavior does NOT occur if executing

within a command script.

Basically this means that it is impossible to wait when opening a file. I have actually tried it and as expected, it does not work.

Therefore, it makes no sense to distinguish between RunWait and Run in the case in which we execute the "start command". It could only be useful for the other case (as the current _RunDOS does). I would say that it is still useful to distinguish between Run() and RunWait() in that case. This means that there are 3 cases instead of 4 and thus we could simply have a single optional parameter called "$runMode":

Func _RunDOS($sCommand, $bRunMode = 1)
  If $bRunMode = 1 Then
    ; This is the original mode for this function in which @ComSpec is called directly,
    ; without invoking the "start command" AND AutoIt WAITS for the command to finish
    Return RunWait(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
  ElseIf $bRunMode = 2 Then
    ; In this mode the "start command" is not used either, but AutoIt DOES NOT WAIT
    ; for the command to end
    Return Run(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
  Else
    ; In this mode, we use the "start command"
    ; Use this mode to OPEN a FILE with its DEFAULT associated PROGRAM
    If @OSTYPE = "WIN32_WINDOWS" Then
      ; Windows 95/98/ME use a slightly different format for the "start command"
      $sFullCommand = @ComSpec & ' /C start "' & $sCommand & '"'
    Else
      ; Newer versions of windows add a "Title" parameter to the "start command"
      ; This parameter is actually ignored when opening files
      $sFullCommand = @ComSpec & ' /C start "AutoIt3 _RunDos" "' & $sCommand & '"'
    EndIf
   
    ; When using the "start command" by default DO NOT WAIT for the command to finish (i.e. use Run())
    Return Run($sFullCommand, "", @SW_HIDE)
  EndIf
EndFunc   ;==>_RunDOS

I think this final version covers all possible cases and also is much simpler than the one I proposed earlier! :P

JdeB, would you like me to write the text explaining the 3 different modes or do you want to do it yourself.

Angel

Share this post


Link to post
Share on other sites

CMD.exe does not wait at a command prompt which is opposite to a batch file command which does. But the reference is to CMD.exe and not the use of Start itself. Upon using Start /Wait, I get the prompt remaining, but key input is not available. The strange thing is the message pump still caches the input and returns the input when the application is closed and control returns.

$command = 'calc'
$pid = Run(@ComSpec & ' /c Start /Wait "Title" "' & $command & '"')
ProcessWaitClose($pid)

Oddly enough, If I use "Title" which seems as not working but calc runs with 1 command prompt window remaining open. If I remove "Title", then a second window opens with execution and "calc" becomes the title. Using the Start command seems very illogical to understand :P . Using XP Pro SP2 here.

I also think that the /wait must be put AFTER the "title" for it to work. But again, as I said, the /wait does not work when the command is the name of a file.

Share this post


Link to post
Share on other sites

Should we also add the /B option to force start to run in the same cmd window ?

In my tests it made no different whatsoever. I think those options are only meant for cases in which you execute a builtin windows command, in which case why would you need to use start? Do you guys see any potential use for that option?

Cheers,

Angel

Share this post


Link to post
Share on other sites

In my tests it made no different whatsoever. I think those options are only meant for cases in which you execute a builtin windows command, in which case why would you need to use start? Do you guys see any potential use for that option?

Cheers,

Angel

Start normally shells a new command window. /b will tell start to use the same cmd window.. You won't see it because its also hidden.

I think we should also include the Run/RunWait option as optional just to give the choice to people.

We need to do some testing before putting it in the standard include file to ensure its backward compatible.

Would be good if you want to have a go at the docs ... i will PM the source TXT file used to generate the HTM file.

:P


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

here's a version that also uses /wait on the start command:

Func _RunDOS($sCommand, $bUseStartCommand = False, $bWaitMode = True)
    Local $sFullCommand
    If $bUseStartCommand Then
        If @OSTYPE = "WIN32_WINDOWS" Then
            ; Windows 95/98/ME use a slightly different format for the "start command"
            $sFullCommand = @ComSpec & ' /c start '
        Else
            ; Newer versions of windows add a "Title" parameter to the "start command"
            ; This parameter is actually ignored when opening files
            $sFullCommand = @ComSpec & ' /c start "AutoIt3 _RunDos"'
        EndIf
        ; When using the "start command" by default DO NOT WAIT for the command to finish (i.e. use Run())
        If $bWaitMode = True Then
            ; If the user FORCED the WAIT, use RunWait()
             $sFullCommand &= ' /wait "' & $sCommand & '"'
            Return RunWait($sFullCommand, "", @SW_HIDE)
        Else
            ; In all other cases (DEFAULT and FORCE to NOT WAIT), call Run()
             $sFullCommand &= ' "' & $sCommand & '"'
            Return Run($sFullCommand, "", @SW_HIDE)
        EndIf
    Else
        ; Do not use the "start command"
        ; In this case by default WAIT for the command to finish (i.e. use RunWait())
        If $bWaitMode = 0 Then
            ; If the user FORCED to NOT WAIT, use Run()
            Return Run($sCommand, "", @SW_HIDE)
        Else
            ; In all other cases (DEFAULT and FORCE to WAIT), call RunWait()
            Return RunWait(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
        EndIf
    EndIf
EndFunc   ;==>_RunDOS

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

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