在 C++ 中使用 CreateProcess() 启动语音识别
Starting Speech Recognition with CreateProcess() in C++
我的简单程序需要帮助,它试图创建一个新进程 运行ning 语音识别。
当我打开 cmd 并输入命令 C:\Windows\Speech\Common\sapisvr.exe -SpeechUX
时,语音识别将成功启动。它甚至会在 运行ning 到 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;
}
首先,我尝试使用带有参数的 运行ning 记事本来测试 CreateProcess 函数以打开现有文件。当我将 notepad.exe 的路径放入第一个参数并将文件名放入命令行参数时,它无法识别它并打开一个新文件。
这也适用于从我的程序中尝试 运行 msconfig.exe,它不带任何参数,所以我想问题出在其他地方,我只是不知道在哪里.
我在网上搜索了 none 个对我有用的答案。我在 Visual Studio 2015 年 Windows 8.1.
工作
感谢您的帮助。
CreateProcess 函数有第二个参数 LPTSTR
。对于此函数的 CreateProcessW
版本,这必须是可写缓冲区,而不是字符串文字。因此,您的程序的行为是未定义的。由于您在调用 CreateProcess
时遇到写入位置的访问冲突,我们假设 CreateProcess
被映射到 CreateProcessW
.
在 link 的帖子中引用了以下内容:
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.
所以修复只是定义一个数组,而不是文字:
TCHAR commandParam[] = TEXT(" -SpeechUX");
if (!CreateProcess(TEXT("C:\Windows\Speech\Common\sapisvr.exe"),
commandParam,
...
}
或者如果传递 NULL 作为第一个参数:
TCHAR commandParam[] = TEXT("C:\Windows\Speech\Common\sapisvr.exe");
//...
if (!CreateProcess(NULL, commandParam, ...
另外,如果CreateProcess
returns一个错误,你应该调用GetLastError and optionally FormatMessage,得到发生的错误,而不是简单地输出有错误。
我的简单程序需要帮助,它试图创建一个新进程 运行ning 语音识别。
当我打开 cmd 并输入命令 C:\Windows\Speech\Common\sapisvr.exe -SpeechUX
时,语音识别将成功启动。它甚至会在 运行ning 到 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;
}
首先,我尝试使用带有参数的 运行ning 记事本来测试 CreateProcess 函数以打开现有文件。当我将 notepad.exe 的路径放入第一个参数并将文件名放入命令行参数时,它无法识别它并打开一个新文件。
这也适用于从我的程序中尝试 运行 msconfig.exe,它不带任何参数,所以我想问题出在其他地方,我只是不知道在哪里. 我在网上搜索了 none 个对我有用的答案。我在 Visual Studio 2015 年 Windows 8.1.
工作感谢您的帮助。
CreateProcess 函数有第二个参数 LPTSTR
。对于此函数的 CreateProcessW
版本,这必须是可写缓冲区,而不是字符串文字。因此,您的程序的行为是未定义的。由于您在调用 CreateProcess
时遇到写入位置的访问冲突,我们假设 CreateProcess
被映射到 CreateProcessW
.
在 link 的帖子中引用了以下内容:
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.
所以修复只是定义一个数组,而不是文字:
TCHAR commandParam[] = TEXT(" -SpeechUX");
if (!CreateProcess(TEXT("C:\Windows\Speech\Common\sapisvr.exe"),
commandParam,
...
}
或者如果传递 NULL 作为第一个参数:
TCHAR commandParam[] = TEXT("C:\Windows\Speech\Common\sapisvr.exe");
//...
if (!CreateProcess(NULL, commandParam, ...
另外,如果CreateProcess
returns一个错误,你应该调用GetLastError and optionally FormatMessage,得到发生的错误,而不是简单地输出有错误。