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

标签 c ping createprocess widechar

<分区>

我正在尝试创建一个 shell,允许用户输入“ping”命令并​​使用 CreateProcess() 根据用户输入执行命令。在处理变量时,我遇到了让 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() 进入一个变量,该变量将用作创建进程的参数?

最佳答案

这里:

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 :

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

即使您不使用 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);

关于c - 将参数传递给 CreateProcess() 在 C 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23508210/

相关文章:

c - 如何从我的 C 程序运行 bcdedit?

c - 如何在线程之间发送变量/信息

r - 隐藏调用系统命令的函数的输出

Meteor 和 C nopoll 应用程序之间的连接丢失

windows - 为什么 %1 很少在 "%1 is not a valid Win32 application."中被替换

c - 位操作良好实践

c - 如何在不使用 "goto"的情况下摆脱这个深层嵌套的循环?

linux - Ping 状态和返回

检查(作为普通用户)管理进程是否正在运行(C,Windows)

c++ - CreateProcess 调用 cmd.exe 包括。没有显示(闪烁)窗口的参数?