10

我需要将命令行参数从 A.exe 传递给 B.exe。如果 A.exe 具有多参数,例如

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

我可以使用

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

启动 B.exe。如何获取原始命令行参数,例如

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

4

7 回答 7

12

如果您在 Windows 上,则使用GetCommandLine获取原始命令行。

请注意,GetCommandLine 还包括 argv[0]。因此,在将 GetCommandLine 的输出传递给 B 之前,您必须超越 argv[0]。

这是一些非错误检查代码来做到这一点

#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;

}

当我运行上述程序时A.exe -a="a" -b="b",我得到以下输出

A.exe -a="a" -b="b"
Command Line is : -a="a" -b="b"
于 2013-01-04T02:53:27.553 回答
7

这是跳过可执行文件名称的唯一正确方法,基于Wine 的 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++;

注意!当前的 Wine 实现,截至 2 月 19 日 2'20 - git commit ,a10267172现在从dlls/shell32/shell32_main.c.dlls/shcore/main.c

于 2016-04-26T21:24:53.400 回答
1

的标准定义main

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

argv变量包含命令行参数。该argc变量指示使用了argv数组中的条目数。

于 2013-01-04T02:46:43.550 回答
1

argv在您的程序开始运行之前,输入到 shell 中的原始字符串由 shell 转换为。除了argv.

如果用户使用引号将空格字符传递到您的参数中怎么办?如果他们使用反斜杠来转义引号内的引号怎么办?不同的 shell 甚至可能有不同的引用规则。

如果您有一个类似的列表argv,您应该尝试找到一个接受它的 API,而不是尝试实现仅辅助实际目标的字符串处理。Microsoft 非常重视安全性,他们当然提供了一些不需要为您的应用程序添加安全漏洞的东西。

我找不到有关任何 C/C++ API 的文档BeginProcess;我有点假设这是 Windows,但无论如何您都应该仔细检查平台的参考手册以获取替代系统调用。

于 2013-01-04T03:01:52.690 回答
0

这就是我将命令行转回 shell args 的方式。有时这很好地回显到输出文件中,以将“使用的参数”与输出一起保存。转义是基本的,对于大多数情况来说已经足够了。

我在命令 (i=0) 处开始输出。如果您只需要参数等,您可以更改为 (i=1)。

//you have to free() the result!, returns null if no args
char *arg2cmd(int argc, char** argv) {
    char *buf=NULL;
    int n = 0;
    int k, i;
    for (i=0; i <argc;++i) {
        int k=strlen(argv[i]);
        buf=( char *)realloc(buf,n+k+4);
        char *p=buf+n;
        char endq=0;
        // this is a poor mans quoting, which is good enough for anything that's not rediculous
        if (strchr(argv[i], ' ')) {
            if (!strchr(argv[i], '\'')) {
                *p++='\'';
                endq='\'';
            } else {
                *p++='\"';
                endq='\"';
            }
        }
        memcpy(p, argv[i], k);
        p+=k;
        if (i < (argc-1)) *p++=' ';
        if (endq) *p++=endq;
        *p='\0';
        n = p-buf;
    }
    return buf;
}

还有一个简单的 cpp 包装器:

std::string arg2string(int argc, char **argv) {
    char *tmp=arg2cmd(argc, argv);
    std::string ret=tmp;
    free(tmp);
    return ret;
}
于 2014-01-03T17:58:48.993 回答
0

在 C++/CLI 中有这样的:

String^ cmdarg = Environment::CommandLine;
于 2019-05-24T00:13:39.897 回答
0

如果您使用的是 Windows,我相信正确的解决方案是调用 GetCommandLine() 以获取完整的命令行,然后调用 PathGetArgs(CommandLine) 从头开始​​删除 arg0(您的 exe 路径)。

于 2020-04-02T12:22:04.507 回答