1

我正在尝试创建一个允许用户输入“ping”命令并​​使用 CreateProcess() 根据用户输入执行命令的 shell。在处理变量时,我遇到了让 ping 命令工作的问题。例如,只要我在字符串前面有 L,下面的代码就可以正常工作。但是,字符串必须由用户输入给出,所以经过一些研究后,我遇到了可能以 wchar_t 变量的形式替换 L 转换。

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() 进入一个变量,该变量将用作创建进程的参数?

4

1 回答 1

3

这里:

wchar_t wideC = "-t www.yahoo.com";

wideC具有类型wchar_t,但使用 type 的文字字符串常量初始化const char*

这是通过以下方式纠正的:

const wchar_t* wideC = L"-t www.yahoo.com";
^^^^^        ^         ^

尽管使用 Win32 可移植字符串指针类型和_T()宏以确保类型一致并支持Unicode 和非 Unicode 构建更安全。

然而,这里的致命缺陷是文档CreateProcess()中的第二个参数不能是const- :CreateProcess()

此函数的 Unicode 版本 CreateProcessW 可以修改此字符串的内容。因此,此参数不能是指向只读内存的指针(例如 const 变量或文字字符串)。如果此参数是一个常量字符串,该函数可能会导致访问冲突。

即使您不使用 const 类型,文字字符串仍然是 const 并且不能在不导致运行时错误的情况下进行修改。你真正需要的是:

TCHAR wideC[] = _T( "-t www.yahoo.com" ) ;

或者如果您选择不注意可移植性建议:

wchar_t wideC[] = L"-t www.yahoo.com" ;

关于接受用户输入,也许wscanf()或更好 -_tscanf()更合适?您不能简单地应用强制转换来更改字符串编码,尤其是因为字符串不是 C 中的一流数据类型,而宽字符串需要额外的存储空间。

话虽如此,Win32 控制台模式对 Unicode 的支持很差且文档不完整。对整个构建强制执行“ANSI”字符模式可能更简单,或者对于这种特定情况,使用函数的显式 ANSI 字符串版本CreateProcessA()- 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);
于 2014-05-07T03:39:48.857 回答