Characters in command getting removed

Hi,

I am running the following code on windows. It is passing a command that requires quotes around one of the parameters: "00100010=lastname^(first name)^" when I run the command directly on the command line it works fine, when running it by rust it fails saying

storescu: 00100010 lastname(first name)

It appears to be removing the = and ^ I can't seem to get it working no matter what I try.
I can replicate the error on the command line by removing the = sign but it still shows the ^ eg:

storescu: 00100010 lastname^(first name)^

let mut test_output = Command::new("storescu.bat")
                    .stdout(Stdio::piped())
                    .arg("-b")
                    .arg("aet")
                    .args( &["-s", "\"00100010=lastname^(first name)^\""])
                    .spawn()
                    .expect("storescu command failed to start");

The Windows command-line has a bunch of legacy "quirks", like how wildcards (e.g. dir *.txt) don't actually get expanded and it's left up to every command to implement their own glob expansion.

In your case, it looks like cmd.exe does something funky when interpreting the arguments passed to a batch script.

https://github.com/PowerShell/PowerShell/issues/8299

The ^ character is used for escaping in cmd.exe. I'm guessing when you run the command from the command-line (cmd.exe) it'll silently double the ^ symbols when formulating the command to be given to CreateProcess(). On the other side, when the batch script is executed I'm guessing cmd.exe will interpret escapes to resolve the ^^ from the command-line into a single ^.

Rust and Powershell don't play these shenanigans so the arguments you write are the arguments sent to the new process. So when the arguments came from Rust (i.e. without the doubled ^) it'll see you've tried to "escape" an open paren (e.g. "^(") and will silently remove the ^.

If it helps, here is link to how Command formats command-line arguments so they can be passed to CreateProcess().

3 Likes

I tried to use double ^^ but it still removes them and the = sign is getting removed. Why is the = sign getting removed?

"00100010=lastname^^(first name)^^"
storescu: 00100010 lastname(first name)

I dunno.

The PowerShell issue I linked to mentioned several possible workarounds and reasons for what you were seeing. Did any of those work for you?

Parsing of ^ in DOS command-line args is magical. The command line is parsed twice, and the first pass removes most of the ^ characters by design. It's not a Rust thing, it's legacy Windows/MS-DOS thing:

https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCMDRULES

1 Like

I tried a few more things - it appears the combination of the \ escape and the ^( is causing this to behave abnormally.

For just this part of the command I removed the \" and it is working normally and passing the ^. It is really odd.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.