Mir*_*ePV 3 c++ windows winapi accessibility process
我需要帮助我的简单程序,它试图创建一个运行语音识别的新进程.当我打开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;
}
Run Code Online (Sandbox Code Playgroud)
首先,我尝试使用带有参数的运行notepad来测试CreateProcess函数以打开现有文件.当我将notepad.exe的路径放到命令行参数的第一个参数和文件名时,它无法识别它并打开了一个新文件.
这整个也适用于尝试从我的程序运行msconfig.exe,它不带任何参数,所以我猜问题是在其他地方,我只是不知道在哪里.我搜索了网络,但没有一个答案对我有用.我在Windows 8.1上的Visual Studio 2015中工作.
感谢帮助.
的CreateProcess的函数具有第二个参数作为LPTSTR.对于CreateProcessW此函数的版本,它必须是可写缓冲区,而不是字符串文字.因此,您的程序的行为是不确定的.由于您在调用时收到写入位置的访问冲突CreateProcess,因此我们假设CreateProcess正在映射到CreateProcessW.
在发布的链接中,这是引用:
此函数的Unicode版本CreateProcessW可以修改此字符串的内容.因此,此参数不能是只读内存的指针(例如const变量或文字字符串).如果此参数是常量字符串,则该函数可能会导致访问冲突.
所以修复只是定义一个数组,而不是文字:
TCHAR commandParam[] = TEXT(" -SpeechUX");
if (!CreateProcess(TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"),
commandParam,
...
}
Run Code Online (Sandbox Code Playgroud)
或者如果将NULL作为第一个参数传递:
TCHAR commandParam[] = TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe");
//...
if (!CreateProcess(NULL, commandParam, ...
Run Code Online (Sandbox Code Playgroud)
此外,如果CreateProcess返回错误,您应该调用GetLastError和FormatMessage,以获取发生的错误,而不是简单地输出有错误.