Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ArgvToCommandLine, the reverse of CommandLineToArgvW #499

Merged
merged 11 commits into from
Mar 20, 2025

Conversation

dunhor
Copy link
Member

@dunhor dunhor commented Jan 22, 2025

A separate project I was working on required this functionality; thought I'd copy it here. The general gist behind its purpose is that CreateProcess* requires a string for the command line as opposed to an argv array; when you're in a scenario where you have an argv array and need to call CreateProcess*, this function is useful. The documentation for the function mentions two specific scenarios in which this is useful, but I'm copying it here for quick reference:

  1. When implementing a "driver" application. That is, an application that consumes some command line arguments, translates others into new arguments, and preserves the rest, "forwarding" the resulting command line to a separate application.
  2. When reading command line arguments from some data storage, e.g. from a JSON array, which then need to get compiled into a command line string that's used for creating a new process.

Note that the documentation for CommandLineToArgvW describes how arguments are parsed; this just does the reverse. The goal of this function is to ensure that the target application's argv array is identical to the one passed into this function. This is potentially problematic if the target application does not use its argv array (e.g. if it gets the command line string directly, e.g. with GetCommandLineW) and instead attempts to perform its own command line processing, which may not handle quotes, etc. identically to CommandLineToArgvW. One notable example is cmd.exe which does not handle some quoted arguments as one would logically expect. For example, cmd.exe "/c" "echo foo" does not behave as you would expect it to:

>cmd "/c" "echo foo"
'"echo foo' is not recognized as an internal or external command,
operable program or batch file.

This is the motivating factor behind ArgvToCommandLineFlags::ForceQuotes. Ideally, we would always surround all arguments with quotes as that's the more efficient thing to do, however as you can see from the above, this is not always safe to do.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
dunhor and others added 3 commits January 22, 2025 15:13
Copy link
Member

@ChrisGuzak ChrisGuzak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love this. forming the CreateProcess args is complicated so glad to see this.

@dunhor dunhor merged commit e8f67c3 into master Mar 20, 2025
11 checks passed
@dunhor dunhor deleted the dunhor/argv2string branch March 20, 2025 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants