如何将 argv 转换为 CreateProcess 的 lpCommandLine 参数?
How do I convert argv to lpCommandLine parameter of CreateProcess?
让我想写一个应用程序,启动另一个应用程序。像这样:
# 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
这里的问题是我在我的 main
函数中得到 char* argv[]
,但我需要将它合并到 LPTSTR
以便将它传递给 CreateProcess
.
有一个 GetCommandLine
函数,但我无法使用它,因为我正在从 Linux 移植代码并绑定到 argc/argv
(否则,这对我来说是一个非常丑陋的 hack ).
我无法轻松地手动合并参数,因为 argv[i]
可能包含空格。
基本上,我想要 CommandLineToArgvW
的反面。有标准方法吗?
没有 Win32 API 执行与 CommandLineToArgvW()
相反的操作。您必须自己格式化命令行字符串。这只不过是基本的字符串连接。
Microsoft 记录了命令行参数的格式(或者至少是 VC++ 编写的应用程序所期望的格式):
Parsing C++ Command-Line Arguments
Microsoft C/C++ startup code uses the following rules when
interpreting arguments given on the operating system command line:
Arguments are delimited by white space, which is either a space or a
tab.
The caret character (^) is not recognized as an escape character or
delimiter. The character is handled completely by the command-line
parser in the operating system before being passed to the argv array
in the program.
A string surrounded by double quotation marks ("string") is
interpreted as a single argument, regardless of white space contained
within. A quoted string can be embedded in an argument.
A double quotation mark preceded by a backslash (\") is interpreted
as a literal double quotation mark character (").
Backslashes are interpreted literally, unless they immediately
precede a double quotation mark.
If an even number of backslashes is followed by a double quotation
mark, one backslash is placed in the argv array for every pair of
backslashes, and the double quotation mark is interpreted as a string
delimiter.
If an odd number of backslashes is followed by a double quotation
mark, one backslash is placed in the argv array for every pair of
backslashes, and the double quotation mark is "escaped" by the
remaining backslash, causing a literal double quotation mark (") to be
placed in argv.
您应该不难编写一个接受字符串数组并将它们连接在一起的函数,对数组中的每个字符串应用上述规则的反向。
您需要重新创建命令行,注意将所有程序名称和参数包含在 "
中。这是通过将 \"
连接到这些字符串来完成的,一个在开头,一个在结尾。
假设要创建的程序名称是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
的第 2nd 个参数
CreateProcess(NULL, command, ...);
Daniel Colascione 的博客提供了关于如何引用论点的最终答案:
我不太愿意在这里引用代码,因为我不知道许可证。基本思路是:
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 运行时库没有执行此操作的功能真是太疯狂了。
下面的代码如果适合你可以看看,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;
}
让我想写一个应用程序,启动另一个应用程序。像这样:
# 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
这里的问题是我在我的 main
函数中得到 char* argv[]
,但我需要将它合并到 LPTSTR
以便将它传递给 CreateProcess
.
有一个 GetCommandLine
函数,但我无法使用它,因为我正在从 Linux 移植代码并绑定到 argc/argv
(否则,这对我来说是一个非常丑陋的 hack ).
我无法轻松地手动合并参数,因为 argv[i]
可能包含空格。
基本上,我想要 CommandLineToArgvW
的反面。有标准方法吗?
没有 Win32 API 执行与 CommandLineToArgvW()
相反的操作。您必须自己格式化命令行字符串。这只不过是基本的字符串连接。
Microsoft 记录了命令行参数的格式(或者至少是 VC++ 编写的应用程序所期望的格式):
Parsing C++ Command-Line Arguments
Microsoft C/C++ startup code uses the following rules when interpreting arguments given on the operating system command line:
Arguments are delimited by white space, which is either a space or a tab.
The caret character (^) is not recognized as an escape character or delimiter. The character is handled completely by the command-line parser in the operating system before being passed to the argv array in the program.
A string surrounded by double quotation marks ("string") is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
A double quotation mark preceded by a backslash (\") is interpreted as a literal double quotation mark character (").
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
If an even number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is interpreted as a string delimiter.
If an odd number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is "escaped" by the remaining backslash, causing a literal double quotation mark (") to be placed in argv.
您应该不难编写一个接受字符串数组并将它们连接在一起的函数,对数组中的每个字符串应用上述规则的反向。
您需要重新创建命令行,注意将所有程序名称和参数包含在 "
中。这是通过将 \"
连接到这些字符串来完成的,一个在开头,一个在结尾。
假设要创建的程序名称是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
的第 2nd 个参数CreateProcess(NULL, command, ...);
Daniel Colascione 的博客提供了关于如何引用论点的最终答案:
我不太愿意在这里引用代码,因为我不知道许可证。基本思路是:
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 运行时库没有执行此操作的功能真是太疯狂了。
下面的代码如果适合你可以看看,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;
}