Jump to content

Generated command works in cmd win, but not ShellExecuteWait ?


Recommended Posts

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!

Link to comment
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?

Link to comment
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,
 

Link to comment
Share on other sites

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
Link to comment
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"')

 

 

Link to comment
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
 Share

×
×
  • Create New...