我正在尝试创建一个允许用户输入" ping"命令并使用CreateProcess()根据用户输入执行命令。我在处理变量时遇到ping命令时遇到了麻烦。例如,只要我在字符串前面有L,下面的代码就可以正常工作。但是,字符串必须由用户输入给出,因此在经过一些研究后,我遇到了以wchar_t变量形式替换L cast的过程。
if (strcmp(buffer, "ping") == 0 || strcmp(buffer, "ping &") == 0){
LPCTSTR path = L"C:\\Windows\\System32\\PING.exe";
LPTSTR link = L"-t www.yahoo.com";
CreateProcess(path,
link,
NULL,
NULL,
0,
0,
NULL,
NULL,
&start,
&info);
if (strcmp(buffer, "ping") == 0){
WaitForSingleObject(info.hProcess, INFINITE);
}
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
printf("MyShell: ");
scanf("%s", buffer);
如果我执行此更改,它将停止工作(控制台崩溃,无输出)。
wchar_t wideC = "-t www.yahoo.com";
LPCTSTR path = L"C:\\Windows\\System32\\PING.exe";
LPTSTR link = wideC;
我已尝试在CreateProcess()参数和外部输出不同类型的变量。我不知道还能做什么。如何将用户scanf()转换为可用作创建进程的参数的变量?
答案 0 :(得分:3)
下面:
wchar_t wideC = "-t www.yahoo.com";
wideC
的类型为wchar_t
,但是使用类型为const char*
的文字字符串常量进行初始化。
更正:
const wchar_t* wideC = L"-t www.yahoo.com";
^^^^^ ^ ^
虽然使用Win32可移植字符串指针类型和_T()
宏更安全,但是为了确保类型协议并同时支持Unicode and non-Unicode builds。
然而,这里的致命缺陷是CreateProcess()
的第二个参数不能是const
- 来自CreateProcess()
documentation:
此函数的Unicode版本CreateProcessW可以修改此字符串的内容。因此,此参数不能是只读内存的指针(例如const变量或文字字符串)。如果此参数是常量字符串,则该函数可能会导致访问冲突。
即使您不使用const类型,文字字符串仍然是const,并且在不引起运行时错误的情况下无法修改。你真正需要的是:
TCHAR wideC[] = _T( "-t www.yahoo.com" ) ;
或者如果您选择不注意可移植性建议:
wchar_t wideC[] = L"-t www.yahoo.com" ;
关于接受用户输入,或许wscanf()
or better - _tscanf()
更合适?您不能简单地应用强制转换来更改字符串编码,尤其是因为字符串不是C中的第一类数据类型,而宽字符串需要额外的存储空间。
所有这一切都表明,Win32控制台模式对Unicode的支持很差且记录不完整。执行" ANSI"可能更简单。整个构建的字符模式,或者对于此特定情况,使用函数CreateProcessA()
的显式ANSI字符串版本 - CreateProcess()
itslef只是CreateProcessW()
或CreateProcessA()
的别名取决于构建的字符集模式。
const char* path = "C:\\Windows\\System32\\PING.exe";
char* link = "-t www.yahoo.com";
CreateProcessA(path,
link,
NULL,
NULL,
0,
0,
NULL,
NULL,
&start,
&info);