如何将argv转换为CreateProcess的lpCommandLine参数?

问题描述 投票:0回答:4

让我想编写一个应用程序,启动另一个应用程序。像这样:

# This will launch another_app.exe
my_app.exe another_app.exe 
# This will launch another_app.exe with arg1, arg and arg3 arguments
my_app.exe another_app.exe arg1 arg2 arg3

这里的问题是我在

char* argv[]
函数中得到
main
,但我需要将其合并到
LPTSTR
才能将其传递给
CreateProcess

有一个

GetCommandLine
函数,但我无法使用它,因为我从 Linux 移植代码并绑定到
argc/argv
(否则,这对我来说是一个非常丑陋的黑客)。

我无法轻松地手动合并参数,因为

argv[i]
可能包含空格。

基本上,我想要

CommandLineToArgvW
的相反。有没有一种标准方法可以做到这一点?

c++ c windows winapi createprocess
4个回答
11
投票

有关如何引用参数的明确答案位于 Daniel Colascione 的博客

https://learn.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way

我不愿意在这里引用代码,因为我不知道许可证。 基本思想是:

for each single argument:
    if it does not contain  \t\n\v\", 
        just use as is
    else
        output "
        for each character
            backslashes = 0
            if character is backslash
                count how many successive backslashes there are
            fi
            if eow
                output the backslashs doubled
                break
            else if char is "
                output the backslashs doubled
                output \"
            else
                output the backslashes (*not* doubled)
                output character
            fi
        rof
        output "
    fi // needs quoting
rof // each argument

如果需要将命令行传递给cmd.exe,请参阅文章(有所不同)。

我认为 Microsoft C 运行时库没有执行此操作的函数,这太疯狂了。


5
投票

没有任何 Win32 API 可以执行与

CommandLineToArgvW()
相反的操作。 您必须自己格式化命令行字符串。 这只不过是基本的字符串连接。

Microsoft 记录了命令行参数的格式(或者至少是 VC++ 编写的应用程序所期望的格式):

解析 C++ 命令行参数

Microsoft C/C++ 启动代码在以下情况下使用以下规则 解释操作系统命令行上给出的参数:

  • 参数由空格分隔,可以是空格,也可以是 选项卡。

  • 插入符号 (^) 未被识别为转义字符或 分隔符。该字符完全由命令行处理 在传递给 argv 数组之前操作系统中的解析器 在节目中。

  • 用双引号括起来的字符串(“string”)是 解释为单个参数,无论包含空格如何 之内。带引号的字符串可以嵌入到参数中。

  • 解释前面带有反斜杠 (\") 的双引号 作为字面双引号字符 (")。

  • 反斜杠按字面解释,除非它们立即 前面加双引号。

  • 如果偶数个反斜杠后面跟着双引号 标记,每对都在 argv 数组中放置一个反斜杠 反斜杠,双引号被解释为字符串 分隔符。

  • 如果奇数个反斜杠后面跟着双引号 标记,每对都在 argv 数组中放置一个反斜杠 反斜杠,并且双引号被“转义” 剩余的反斜杠,导致文字双引号 (") 放置在 argv 中。

编写一个接受字符串数组并将它们连接在一起的函数应该不难,对数组中的每个字符串应用上述规则的相反规则。


0
投票

您需要重新创建命令行,注意将所有程序名称和参数包含在

"
中。这是通过将
\"
连接到这些字符串来完成的,一个在开头,一个在结尾。

假设要创建的程序名称是

argv[1]
,第一个参数
argv[2]
等...

char command[1024]; // size to be adjusted
int i;
for (*command=0, i=1 ; i<argc ; i++) {
   if (i > 1) strcat(command, " ");
   strcat(command, "\"");
   strcat(command, argv[i]);
   strcat(command, "\"");
}

使用 CreateProcess 的第 2 个nd参数

CreateProcess(NULL, command, ...);

-1
投票

如果您需要的话,您可以查看下面的代码,txt数组sz可以用作字符串指针。我添加了对 Unicode 和 MBCS 的代码支持,

            #include <string>
            #include <vector>

            #ifdef _UNICODE
                #define String std::wstring
            #else
                #define String std::string
            #endif 

            int _tmain(int argc, _TCHAR* argv[])
            {
                TCHAR sz[1024] = {0};
                std::vector<String> allArgs(argv, argv + argc);

                for(unsigned i=1; i < allArgs.size(); i++)
                {
                    TCHAR* ptr = (TCHAR*)allArgs[i].c_str();
                    _stprintf_s(sz, sizeof(sz), _T("%s %s"), sz, ptr);
                }

                return 0;
            }
© www.soinside.com 2019 - 2024. All rights reserved.