Mbee

Generated command works in cmd win, but not ShellExecuteWait ?

5 posts in this topic

I'm having a problem executing a command line (with many parameters) from within my script using ShellExecuteWait().  As a debug step, my script outputs the generated cmd line and parameters to a temp text file. If I start a cmd window and cut and paste the cmd from this temp file, it works perfectly.  If, however, I call ShellExecuteWait() within the script, the tool I'm running (mkvmerge.exe) always returns error code 2 (invalid cmd line).

Note that mkvmerge requires a strangely "escaped" parameter list; e.g...

"C:\Program Files\MKVToolNix\mkvmerge.exe" --output ^"L:/Path1/OutVid.mkv^" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none ^"^(^" ^"L:/Path2/SrcVid.mkv^" ^"^)^"

As you can see, mkvmerge mandates that backslashes in paths be replaced with forward-slashes, that quote marks be "escaped" by preceding them with "^" (as well as parentheses), etc.  I'm pretty sure this weirdness is required because mkvmerge was designed for non-Windows OSes (or something like that).

Is that part of the problem, do you think?

Under Windows, do any of the quote marks need to be doubled (i.e, should it be ^""L:/Path1/OutVid.mkv^"")?  How about the slashes in the path names (i.e., should it be ^"L://Path1//OutVid.mkv^")?

 

Finally, am I correct to assume that I must use ShellExecuteWait() because one cannot pass command line parameters with RunWait()?  If not, is there any benefit of using one over the other?

 

Thanks a great deal for your consideration and assistance!

Share this post


Link to post
Share on other sites



Post the code that you used for your ShellExecuteWait so we can see how you're sending the parameters.

ShellExecuteWait("mkvmerge.exe", '--output ^"L:/Path1/OutVid.mkv^" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none ^"^(^" ^"L:/Path2/SrcVid.mkv^" ^"^)^"', "C:\Program Files\MKVToolNix\")

Does this not work?

Share this post


Link to post
Share on other sites

If the string contains "quotation marks/quotes" then use 'apostrophe/single quotes' to cover.

If the string contains 'apostrophe/single quotes' then use "quotation marks/quotes" to cover.

 

Example:
 

Local $quotes = "I'am Trong!"
Local $apostrophe = 'Use "quote marks" for this string!'

RunWait('"' & @ProgramFilesDir & "\MKVToolNix\mkvmerge.exe" & '" ' & '--output "D:/Path1/OutVid.mkv" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none "D:/Path2/SrcVid.mkv"')
ShellExecuteWait(@ProgramFilesDir & "\MKVToolNix\mkvmerge.exe", '--output "D:/Path1/OutVid.mkv" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none "D:/Path2/SrcVid.mkv"')

 


Regards,
 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

15 hours ago, InunoTaishou said:

Post the code that you used for your ShellExecuteWait so we can see how you're sending the parameters.

ShellExecuteWait("mkvmerge.exe", '--output ^"L:/Path1/OutVid.mkv^" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none ^"^(^" ^"L:/Path2/SrcVid.mkv^" ^"^)^"', "C:\Program Files\MKVToolNix\")

Thank you for your reply, InunoTaishou!

Here's the essential code for creating the full parameter string and passing it to ShellExecuteWait() (the example I gave in my OP was shortened)...

Const   $C_OutCmdPart1 = " --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none " _
                         & "--language 1:eng --default-track 1:yes --compression 1:none "
Const   $C_OutCmdPart2 = ' ^"^)^" --sub-charset 0:US-ASCII --language 0:eng --default-track 0:no --compression 0:none'
Const   $C_OutCmdPart3 = ' ^"^)^" --track-order 0:0,0:1,1:0'
;
;
$L_SubSrcPath = $L_SubFileList[$L_CurSubIndex]
$L_EscMkvSrcPath = _EscapePath( $L_MkvSrcPath )
$L_EscMkvOutPath = _EscapePath( $L_MkvOutPath )
$L_EscSubSrcPath = _EscapePath( $L_SubSrcPath )
;
$L_CmdParams = " --ui-language en --priority higher --output " & $L_EscMkvOutPath & $C_OutCmdPart1 & '^"^(^" ' _
                & $L_EscMkvSrcPath & $C_OutCmdPart2 & ' ^"^(^" ' & $L_EscSubSrcPath & $C_OutCmdPart3
$L_Stat = ShellExecuteWait( "C:\Program Files\MKVToolNix\mkvmerge.exe", $L_CmdParams, @ProgramFilesDir, $SHEX_OPEN )
If @error <> 0 Then                                 ; Invalid call
    MsgBox($MB_OK, $C_MainTitle, "Invalid ShellExecuteWait() -- Exiting.")
    Exit 0
EndIf
MsgBox($MB_OK, $C_MainTitle, "MkvMerge Cmd Complete. Return Status = " & $L_Stat )
Exit
;
;
Func _EscapePath( $fpl_NormPath )
    Local   $fl_WorkEscStr
;
    $fl_WorkEscStr = StringReplace( $fpl_NormPath, "(", "^(", 0, $STR_NOCASESENSEBASIC )
    $fl_WorkEscStr = StringReplace( $fl_WorkEscStr, ")", "^)", 0, $STR_NOCASESENSEBASIC )
    $fl_WorkEscStr = StringReplace( $fl_WorkEscStr, "!", "^!", 0, $STR_NOCASESENSEBASIC )
    $fl_WorkEscStr = StringReplace( $fl_WorkEscStr, "\", "/", 0, $STR_NOCASESENSEBASIC )
    Return '^"' & $fl_WorkEscStr & '^"'
EndFunc

The output error message is always "MkvMerge Cmd Complete. Return Status = 2"

As I said in my OP, when I write the generated command & parameter strings to a text file, if I cut & paste into a CMD window, the command is always correct and completes successfully.  Therefore, there MUST be a difference between what works in a CMD line versus what's necessary for ShellExecuteWait().  What is it?

ETA: Here is the exact output cmd & params text line written to the debug text file I've referred to in this thread:

"C:\Program Files\MKVToolNix\mkvmerge.exe" --ui-language en --priority higher --output ^"L:/=MEDIA=/S01E01_Final.mkv^" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none ^"^(^" ^"L:/=MEDIA=/S01E01.mkv^" ^"^)^" --sub-charset 0:US-ASCII --language 0:eng --default-track 0:no --compression 0:none ^"^(^" ^"L:/=MEDIA=/S01E01.srt^" ^"^)^" --track-order 0:0,0:1,1:0

 

Edited by Mbee
Added generated cmd line

Share this post


Link to post
Share on other sites
9 hours ago, Trong said:

Thanks, Trong.

But as you can see from the new code snippet I posted above, I already knew how to handle these and wrote my code appropriately.

Thanks anyway...
 

Local $quotes = "I'am Trong!"
Local $apostrophe = 'Use "quote marks" for this string!'

RunWait('"' & @ProgramFilesDir & "\MKVToolNix\mkvmerge.exe" & '" ' & '--output "D:/Path1/OutVid.mkv" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none "D:/Path2/SrcVid.mkv"')
ShellExecuteWait(@ProgramFilesDir & "\MKVToolNix\mkvmerge.exe", '--output "D:/Path1/OutVid.mkv" --no-subtitles --language 0:eng --default-track 0:yes --compression 0:none --language 1:eng --default-track 1:yes --compression 1:none "D:/Path2/SrcVid.mkv"')

 

 

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

  • Similar Content

    • Simpel
      By Simpel
      Hi.
      Local $sPDFtk = FileGetShortName(@ScriptDir & "\pdftk.exe") Local $sInputPDF = FileGetShortName(@ScriptDir & "\Prodis_Test.pdf") Local $sSig_1 = FileGetShortName(@ScriptDir & "\Sig_1.pdf") Local $sTempPDF = FileGetShortName(@ScriptDir & "\Prodis_Test_TEMP.pdf") $iSuccess = ShellExecuteWait($sPDFtk, $sInputPDF & " stamp " & $sSig_1 & " output " & $sTempPDF, "", "", @SW_HIDE) @ScriptDir is "H:\_Conrad lokal\Downloads\AutoIt3\_COX". As you can see there is a space in the path.
      I know that ShellExecuteWait is working with FileGetShortName at the filename. It seems to me that I can't pass the parameters that way. But without FileGetShortName it's not working too.
      Ideas? Regards, Conrad
    • Chimaera
      By Chimaera
      Im running a test to make sure browsers connect properly to the internet like this
      If ProcessExists('iexplore.exe') Then ProcessClose('iexplore.exe') If ProcessExists('chrome.exe') Then ProcessClose('chrome.exe') If ProcessExists('firefox.exe') Then ProcessClose('firefox.exe') Sleep(200) ShellExecuteWait('iexplore.exe') Sleep(200) If FileExists(@ProgramFilesDir & '\Google\Chrome\Application\chrome.exe') Then ShellExecuteWait('chrome.exe') Sleep(200) If FileExists(@ProgramFilesDir & '\Mozilla Firefox\firefox.exe') Then ShellExecuteWait('firefox.exe') Sleep(200) If Not ProcessExists('iexplore.exe') Or Not ProcessExists('chrome.exe') Or Not ProcessExists('firefox.exe') Then Switch MsgBox($MB_YESNO + $MB_ICONWARNING + $MB_DEFBUTTON2, 'Browsers Check', 'Did All Browsers Work') Case $IDYES GUICtrlSetImage($BrowserIcon, $tick) RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\Setup\Simple', 'Browser', 'REG_SZ', _Date_Time_SystemTimeToDateTimeStr($CuDate)) Case $IDNO GUICtrlSetImage($BrowserIcon, $cross) RegWrite('HKEY_LOCAL_MACHINE\SYSTEM\Setup\Simple', 'Browser', 'REG_SZ', 'NotCompleted') EndSwitch EndIf But it hangs like a git between 
      ShellExecuteWait('iexplore.exe') Sleep(200) If FileExists(@ProgramFilesDir & '\Google\Chrome\Application\chrome.exe') Then ShellExecuteWait('chrome.exe') If i reduce it to this
      ShellExecuteWait('iexplore.exe') Sleep(200) ;~ If FileExists(@ProgramFilesDir & '\Google\Chrome\Application\chrome.exe') Then ShellExecuteWait('chrome.exe') Sleep(200) ;~ If FileExists(@ProgramFilesDir & '\Mozilla Firefox\firefox.exe') Then ShellExecuteWait('firefox.exe') Its instant but then it gives an error that firefox cant be found if its not installed
      Any suggestions how to stop this hanging
    • AntonioGNAL
      By AntonioGNAL
      Hi guys,
      I've been trying to create a registry key export for a while, but i'm hitting my head against a wall here.
      I've tried a huge amount of combinations for both:
      ShellExecuteWait & RunWait commands, but they never complete the task.
      ;This is the reg key Global $targetHistory = "HKEY_CURRENT_USER\Software\Hewlett-Packard\HP Print Settings\Ubicación predeterminada\Target History" RegeditTH($logHandler, $regBackup, $targetHistory) Func RegeditTH($logHandler, $regBackup, $targetHistory) Local $THRegBkup = $regBackup & "ExportTH.bat" Local $THRegHandler Local $removeFile _FileWriteLog($logHandler, "INFORMATION: ExportTH.bat storage directory = " & $regBackup & "." & @CRLF) ; Create a file to write registry keys to. If Not _FileCreate($THRegBkup) Then ; Error flags: ; 1 - Error opening specified file ; 2 - File could not be written to ; [OPTIONAL] Display a pop-up message for notification, error creating the file ;MsgBox($MB_SYSTEMMODAL, "Error", " Error reating reg file. Error Code:" & @error & ".") _FileWriteLog($logHandler, "WARNING: Registry export file not created." & @CRLF) Else $THRegHandler = FileOpen ($THRegBkup ,$FO_APPEND) If $THRegHandler <> -1 Then _FileWriteLog($logHandler, "INFORMATION: Performing registry backup for Target History keys." & @CRLF) FileWrite($THRegHandler, "@echo off" & @CRLF) ;FileWrite($THRegHandler, "regedit.exe /e " & $regBackup & "TargetHistory.reg " & '"HKEY_CURRENT_USER\Software\Hewlett-Packard\HP Print Settings\Ubicación predeterminada\Target History"' & @CRLF) FileWrite($THRegHandler, "Reg export " & '"HKEY_CURRENT_USER\Software\Hewlett-Packard\HP Print Settings\Ubicación predeterminada\Target History" ' & $regBackup & "TargetHistory.reg " & "/y" & @CRLF) FileWrite($THRegHandler, "dir " & $regBackup & @CRLF) FileWrite($THRegHandler, "dir " & $regBackup & " >> " & $regBackup & "dir.txt" & @CRLF) FileWrite($THRegHandler, "pause" & @CRLF) FileWrite($THRegHandler, "exit /B" & @CRLF) FileWrite($THRegHandler, "exit" & @CRLF) FileClose($THRegHandler) ;RunWait(@ComSpec & " /k " & "regedit.exe /e " & $regBackup & "TargetHistory2.reg " & $targetHistory) ;ShellExecuteWait(@ComSpec , "/k regedit.exe /e " & $regBackup & "TargetHistory.reg " & $targetHistory) ;ShellExecuteWait(@ComSpec & " /c " & $THRegBkup, @SW_HIDE) RunWait(@ComSpec & " /c " & $THRegBkup) ; Error Flag is set to non-zero in case of failure If @error <> 0 Then _FileWriteLog($logHandler, "ERROR: Registry export failed." & @CRLF) Else _FileWriteLog($logHandler, "WARNING: ExportTH.bat file could not be opened." & @CRLF) EndIf $removeFile = FileDelete($THRegBkup) If $removeFile Then _FileWriteLog($logHandler, "INFORMATION: File " & $THRegBkup & " deleted." Else _FileWriteLog($logHandler, "WARNING: File " & $THRegBkup & " not deleted or it does not exist." EndIf EndIf ; Close the handle returned by FileOpen. FileClose($THRegHandler) EndFunc This is the function i'm using for the call.
      Since i was not going anywhere with the AutoIt direct executions, i even tried creating a bat/cmd file with the command for a reg export to create the reg file i needed. However, even running the bat file is not working for me. I mean, the bat is executed, as you can see i created a couple of "dir" commands to be prompted and sent to a file. And they are showing up, but the registry export is never being executed.
      The best i could get was a message saying it was impossible to locate the key, but i know with 100% certainty the key exists in that path (because i'm creating and deleting it all the time).
      Can anyone point out any possible mistakes?
      Here you can see the error message in the CMD prompt:

      Thanks!
    • Kevinsyel
      By Kevinsyel
      I was wondering if there are any developers out there who are having issues running AutoIT code on the latest revision of Win8?
      I recently (about 4 months ago) wrote an auto-installer that pulled tools from a server and ran an auto install of each tool on systems.
      This worked fine for revisions 8250, 8375 and 8400. However, when Win8 revision 8441 came around, I noticed some issues running some installers.
      Now with the newest revision, 8520, it seems that FileCopy, DirCopy, ShellExecute, ShellExecuteWait, Run, and RunWait are all either locking up, or just failing to run.

      The steps I take are:

      Read from a cfg file the path of the installer, and any installer arguments
      download installer from path
      use ShellExecuteWait on installer with arguments

      In the past, I've had no problems with this same exact code. UAC is off, #RequireAdmin is set, application is run as administrator, and even powershell is set to "Set-ExecutionPolicy UnRestricted"

      Has anybody else had this problem? Anybody have workarounds?