Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the raw command line arguments

Tags:

c++

c

windows

I need to pass command line arguments from A.exe to B.exe. If A.exe with multi-args like

A.exe -a="a" -b="b"'

and I can use

BeginProcess("B.exe", **args!**)

to start B.exe. How can I get the raw command line arguments like

'-a="a" -b="b"'

like image 234
miaodadao Avatar asked Jan 04 '13 02:01

miaodadao


People also ask

How do I get command line arguments?

If you want to pass command line arguments then you will have to define the main() function with two arguments. The first argument defines the number of command line arguments and the second argument is the list of command line arguments.

How do I find command line arguments in Visual Studio?

To set command-line arguments in Visual Studio, right click on the project name, then go to Properties. In the Properties Pane, go to "Debugging", and in this pane is a line for "Command-line arguments." Add the values you would like to use on this line.

Where does command line arguments are get stored?

All the command line arguments are stored in a character pointer array called argv[ ]. Total count of command line arguments including file path argument is stored in a integer parameter called argc.


4 Answers

If you are on Windows, you use GetCommandLine to get the raw command line.

Note that GetCommandLine also includes argv[0]. So you will have to go beyond argv[0] from the output of GetCommandLine before passing it to B.

This is some non-error checked code to do that

#include <string.h>
#include <windows.h>
#include <iostream>
#include <ctype.h>

int main(int argc, char **argv)
{
    LPTSTR cmd  = GetCommandLine();

    int l = strlen(argv[0]);

    if(cmd == strstr(cmd, argv[0]))
    {
        cmd = cmd + l;
        while(*cmd && isspace(*cmd))
            ++cmd;
    }

    std::cout<<"Command Line is : "<<cmd;

}

When I run the above program as A.exe -a="a" -b="b", I get the following output

A.exe -a="a" -b="b"
Command Line is : -a="a" -b="b"
like image 105
user93353 Avatar answered Oct 18 '22 21:10

user93353


Here is the one and only correct way to skip the executable name, based on Wine's implementation of CommandLineToArgvW:

char *s = lpCmdline;
if (*s == '"') {
    ++s;
    while (*s)
        if (*s++ == '"')
            break;
} else {
    while (*s && *s != ' ' && *s != '\t')
        ++s;
}
/* (optionally) skip spaces preceding the first argument */
while (*s == ' ' || *s == '\t')
    s++;

Note! Current Wine implementation, as of Feb 19 2'20 - git commit a10267172, is now moved from dlls/shell32/shell32_main.c to dlls/shcore/main.c.

like image 40
benrg Avatar answered Oct 18 '22 20:10

benrg


The standard definition of main is

int main(int argc, char* argv[])

The argv variable contains the command-line arguments. The argc variable indicates how many entries in the argv array are used.

like image 25
Code-Apprentice Avatar answered Oct 18 '22 20:10

Code-Apprentice


The raw string typed into the shell is converted by the shell into argv before your program begins running. I've never heard of an operating system or shell providing a "raw" command-line in addition to argv.

What if the user used quotes to pass a space character into your arguments? What if they used a backslash to escape a quote inside the quotes? Different shells may even have different quoting rules.

If you have a list like argv, you should try to find an API that accepts that rather than attempting to implement string processing which is only auxiliary to the actual goal. Microsoft is serious about security and they certainly provide something that doesn't require adding a security hole to your application.

I can't find documentation about any C/C++ API BeginProcess; I'm kind of assuming this is Windows but in any case you should double check your platform's reference manual for an alternative system call.

like image 25
Potatoswatter Avatar answered Oct 18 '22 21:10

Potatoswatter