我要如何转换 argv 来转换 Create Process 的 lpCommandLine 参数?
原标题:How do I convert argv to lpCommandLine parameter of CreateProcess?
Let I want to write an application, that launches another application. Like this:
# 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
The problem here is that I m getting char* argv[] in my main function, but I need to merge it to LPTSTR in order to pass it to CreateProcess.
There is a GetCommandLine function, but I cannot use it because I m porting code from Linux and tied to argc/argv (otherwise, it s a very ugly hack for me).
I cannot easily merge arguments by hand, because argv[i] might contain spaces.
Basically, I want the reverse of CommandLineToArgvW. Is there a standard way to do this?
最佳回答
The definitive answer on how to quote arguments is on Daniel Colascione s blog:
https://learn.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
I am reluctant to quote the code here because I don t know the license. The basic idea is:
for each single argument:
if it does not contain
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
If you need to pass the command line to cmd.exe, see the article (it s different).
I think it is crazy that the Microsoft C runtime library doesn t have a function to do this.
问题回答
There is no Win32 API that does the reverse of CommandLineToArgvW(). You have to format the command line string yourself. This is nothing more than basic string concatenation.
Microsoft documents the format for command-line arguments (or at least the format expected by VC++-written apps, anyway):
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.
It should not be hard for you to write a function that takes an array of strings and concatenates them together, applying the reverse of the above rules to each string in the array.
You need to recreate the command line, taking care of having all program name and arguments enclosed in ". This is done by concatenating a " to these strings, one at the beginning, one at the end.
Assuming the program name to be created is argv[1], the first argument argv[2] etc...
char command[1024]; // size to be adjusted
int i;
for (*command=0, i=1 ; i
1) strcat(command, " ");
strcat(command, """);
strcat(command, argv[i]);
strcat(command, """);
}
Use the 2nd argument of CreateProcess
CreateProcess(NULL, command, ...);
You can check out the below code if it suits your need, the txt array sz can be used as a string pointer. I have added code support for both Unicode and MBCS,
#include
#include
#ifdef _UNICODE
#define String std::wstring
#else
#define String std::string
#endif
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR sz[1024] = {0};
std::vector 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;
}
相关问题
Undefined reference
I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically.
First, I have namespace LCD. Then I ...
Where do I get sample code in C++ creating iterator for my own container?
I have been searching for sample code creating iterator for my own container, but I haven t really found a good example. I know this been asked before (Creating my own Iterators) but didn t see any ...
C++ Equivalent of Tidy
Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up.
I am ...
Template Classes in C++ ... a required skill set?
I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?
Print possible strings created from a Number
Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad.
i.e. for 1,0-> No Letter
for 2->...
typedef ing STL wstring
Why is it when i do the following i get errors when relating to with wchar_t?
namespace Foo
{
typedef std::wstring String;
}
Now i declare all my strings as Foo::String through out the program, ...
C# Marshal / Pinvoke CBitmap?
I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class.
My import looks like this:
[DllImport(@"test.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr ...
Window iconification status via Xlib
Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?