Запуск распознавания речи с помощью CreateProcess () в C++


Мне нужна помощь с моей простой программой, которая пытается создать новый процесс, запускающий распознавание речи. Когда я открываю cmd и набираю команду C:WindowsSpeechCommonsapisvr.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 processn");
        return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);

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

    return 0;
}

Сначала я попытался протестировать функцию CreateProcess, запустив блокнот с аргументом, чтобы открыть существующий файл. Когда я ставлю путь к блокноту.exe к первому параметру и имя файла к параметру командной строки, он не распознал его и открыл новый файл вместо этого.

Все это относится также и к попытке запустить msconfig.exe из моей программы, которая не принимает никаких параметров, так что я предполагаю, что проблема где-то еще, я просто понятия не имею, где. Я поискал в интернете, и ни один из ответов на самом деле не работал для меня. Я работаю в Visual Studio 2015 на Windows 8.1.

Спасибо за помощь.

1 3

1 ответ:

ФункцияCreateProcess имеет второй аргумент в виде LPTSTR. Для версии CreateProcessW этой функции это должен быть записываемый буфер, а не строковый литерал. Таким образом, поведение вашей программы не определено. Поскольку при вызове CreateProcess Вы получаете запись о нарушении доступа к местоположению, мы будем считать, что CreateProcess сопоставляется с CreateProcessW.

По ссылке, опубликованной, вот цитата:

Unicode-версия этой функции, CreateProcessW, может изменять содержимое этой строки. Поэтому этот параметр не может быть указателем на память только для чтения (например, переменную const или литеральную строку). Если этот параметр является постоянной строкой, функция может вызвать нарушение доступа.

Поэтому исправление заключается в простом определении массива, а не литерала:

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 возвращает ошибку, вы должны вызвать GetLastError и дополнительно FormatMessage , чтобы получить ошибку, которая произошла, а не просто вывести, что есть ошибка.