使用C ++中的CreateProcess()开始语音识别

时间:2016-02-12 11:43:54

标签: c++ windows winapi process accessibility

我需要帮助我的简单程序,它试图创建一个运行语音识别的新进程。 当我打开cmd并输入命令C:\Windows\Speech\Common\sapisvr.exe -SpeechUX时,语音识别将成功启动。即使在system(C:\\Windows\\...)运行时它也会启动,这基本上只是模仿cmd。 但是,使用如下CreateProcess()创建新进程时,该函数将失败。如果我将整个路径和参数放入第二个参数CreateProcess(NULL, TEXT("C:\\Windows...\\sapisvr.exe -SpeechUX"), ...),那么我得到一个运行时异常:访问冲突写入位置

#include <windows.h>
int main()
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (!CreateProcess(
    TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"), //Module name
    TEXT(" -SpeechUX"),     //command line params
    NULL,       //Process attributes
    NULL,       //Thread attributes
    FALSE,      //Handle inheritance
    0,          //No creation flags
    NULL,       //Use parent's environment
    NULL,       //Use parent's starting directory
    &si,        //Pointer to STARTUPINFO structure
    &pi ))      //Pointer to PROCESS_INFORMATION structure
    {
        printf("error creating process\n");
        return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

首先,我尝试使用带有参数的运行notepad来测试CreateProcess函数以打开现有文件。当我将notepad.exe的路径放到命令行参数的第一个参数和文件名时,它无法识别它并打开了一个新文件。

这整个也适用于尝试从我的程序运行msconfig.exe,它不带任何参数,所以我猜问题是在其他地方,我只是不知道在哪里。 我搜索了网络,但没有一个答案对我有用。我在Windows 8.1上的Visual Studio 2015中工作。

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

CreateProcess函数的第二个参数为[[ 1. 2.] [ 3. 4.] [ 1. 2.] [ 3. 4.] [ 1. 2.] [ 3. 4.]] 。对于此函数的LPTSTR版本,它必须是可写缓冲区,而不是字符串文字。因此,您的程序的行为是不确定的。由于您在调用CreateProcessW时收到了写入地址的访问权限,因此我们假设CreateProcess已映射到CreateProcess

在发布的链接中,这是引用:

  

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

所以修复只是定义一个数组,而不是文字:

CreateProcessW

或者如果将NULL作为第一个参数传递:

TCHAR commandParam[] = TEXT(" -SpeechUX");

if (!CreateProcess(TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"), 
                   commandParam,
                   ...
   }

此外,如果TCHAR commandParam[] = TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"); //... if (!CreateProcess(NULL, commandParam, ... 返回错误,您应该调用GetLastErrorFormatMessage,以获取发生的错误,而不是简单地输出错误。