[英]How to send wstring buffer to stdin of a child process?
I'm having trouble writing a WString to the STDIN of a child process. 我在将WString写入子进程的STDIN时遇到麻烦。 If I have only acii character string (eg: @WSX3edc), the code works fine, but if it contains a non ascii character (eg: @WSX3edcß) it fails.
如果我只有acii字符串(例如:@ WSX3edc),则代码可以正常工作,但是如果它包含非ascii字符(例如:@WSX3edcß),它将失败。
The child process is 7zr.exe (7Zip cmd line version). 子进程是7zr.exe(7Zip cmd行版本)。 The input I'm writing to the STDIN is the password to extract the file.
我正在写到STDIN的输入是提取文件的密码。
// inject password
wPassword.append(password);
wPassword.append(L"\n"); \\For carriage return
...
DWORD dwBytesToWrite = wPassword.length()*sizeof(wchar_t);
DWORD dwBytesWritten = 0;
char szBuffer[1024] = "\0";
wcstombs(szBuffer, wPassword.c_str(),wcslen(wPassword.c_str())+1);
dwBytesToWrite = strlen(szBuffer);
if (!WriteFile(hInput, szBuffer, dwBytesToWrite, &dwBytesWritten, NULL)) {
std::cout<<"write file failed"<<GetLastError()<<std::endl;
goto Cleanup;
}
The writefile always succeed but some how the file extraction is not successful due to faulty password injecting mechanism. writefile总是成功,但是由于密码注入机制错误,文件提取无法成功。
Createprocess for this looks like : (si object has the STDIN and STDOUT streams set using a CreatePipe earlier) 为此的Createprocess看起来像:(si对象先前使用CreatePipe设置了STDIN和STDOUT流)
if(!CreateProcess((LPWSTR)cmd, (LPWSTR)cmdArgs, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi)) {
std::cout<<"7zr.exe process creation failed "<<GetLastError()<<std::endl;
goto Cleanup;
}
Note : 7zr.exe works just fine with this particular password , if we run it on command-line and paste this password. 注意:如果在命令行上运行并粘贴此密码,则使用该特定密码的7zr.exe可以正常工作 。 The extraction works fine.
提取工作正常。
If the narrow character set doesn't have the relevant password character, you can't use this approach. 如果窄字符集没有相关的密码字符,则不能使用此方法。 Instead find what option
7zr
has for specifying the password. 而是找到
7zr
用于指定密码的选项。 I don't have an executable called 7zr
but I do have 7z
, and the command 7z | find /i "pass"
我没有名为
7zr
的可执行文件,但确实有7z
,命令7z | find /i "pass"
7z | find /i "pass"
worked nicely. 7z | find /i "pass"
效果很好。
In other news: 在其他新闻中:
The variable dwBytesToWrite
is initialized with one value, only to be reassigned a few lines later, without having been used. 变量
dwBytesToWrite
用一个值初始化,仅在以后几行重新分配,而没有使用。
goto Cleanup
is generally ungood in C++. goto Cleanup
在C ++中, goto Cleanup
通常是不好的。 If you want guaranteed cleanup use a destructor (the technique called RAII, read up on it). 如果要保证清除,请使用析构函数(称为RAII的技术,请继续阅读)。
Microsoft's Hungarian notation, with prefixes such as sz
and dw
, is generally an abomination. 微软的匈牙利符号,带有
sz
和dw
前缀,通常是可憎的。 It once, in the 1980's, supported the help system in Microsoft's Programmer's Workbench. 在1980年代,它曾经在Microsoft的Programmer's Workbench中支持帮助系统。 AFAIK that product hasn't existed the last 30 years or so.
AFAIK该产品在过去30年左右不存在。
The C cast in (LPWSTR)cmd
can easily introduce a bug. (LPWSTR)cmd
为(LPWSTR)cmd
的C很容易引入错误。 Use const_cast
where you want to cast constness. 在要
const_cast
地方使用const_cast
。 Then it would be more clear that this cast is incorrect: you need a mutable buffer. 然后,更清楚的是此强制转换是不正确的:您需要一个可变的缓冲区。
Instead of reporting a failure to the standard output stream, via std::cout
, consider using the standard error stream, via either std::cerr
or std::clog
. 可以通过
std::cerr
或std::clog
使用标准错误流,而不是通过std::cout
向标准输出流报告故障。 Better, don't do i/o at the place where a failure is detected, but throw an exception to let the calling code deal with it. 更好的是,不要在检测到故障的地方进行I / O操作,而要抛出异常以使调用代码进行处理。 The calling code can't remove output that's already, uh, output.
调用代码无法删除已经输出的输出。
wcslen(wide)
returns the number of wide characters in its argument wide
( see ). wcslen(wide)
返回其自变量的宽字符数wide
( 见 )。
wcstombs(narrow,wide,len)
writes no more than len
bytes to narrow
( see ). wcstombs(narrow,wide,len)
最多可以写入len
个字节来narrow
( 请参阅 len
)。
Now if we always had one wide character = one narrow character = one byte, it wouldn't have much sense to have two varieties of characters, would it? 现在,如果我们总是有一个宽字符=一个窄字符=一个字节,那么拥有两种字符就没有多大意义了,是吗?
As soon as you have a wide character that translates to more than one narrow character, there is undefined behaviour. 一旦将宽字符转换为多个窄字符,就会出现不确定的行为。
Since your szBuffer
is of fixed size, you could just as well write 由于您的
szBuffer
具有固定大小,因此您可以编写
wcstombs(szBuffer, wPassword.c_str(), sizeof(szBuffer));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.