将参数传递给CreateProcess()在C中不起作用

时间:2014-05-07 03:29:06

标签: c ping createprocess widechar

我正在尝试创建一个允许用户输入" 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()转换为可用作创建进程的参数的变量?

1 个答案:

答案 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);