API Windows - путь CreateProcess() с пространством

Как передать путь с пространством функции CreateProcess()?

Следующие работы

STARTUPINFO si;
            PROCESS_INFORMATION pi;

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

            if( !CreateProcess(_T("c:\\installer\\ew3d.exe"),    // No module name (use command line)
                _T("c:\\installer\\ew3d.exe /qr"),//argv[1],        // Command line
                NULL,           // Process handle not inheritable
                NULL,           // Thread handle not inheritable
                FALSE,          // Set handle inheritance to FALSE
                0,              // No creation flags
                NULL,           // Use parent environment block
                NULL,           // Use parent starting directory 
                &si,            // Pointer to STARTUPINFO structure
                &pi )           // Pointer to PROCESS_INFORMATION structure
                ) 
            {
                printf( "CreateProcess failed (%d).\n", GetLastError() );
                return false;
            }

            //Wait until child process exits.
            WaitForSingleObject( pi.hProcess, INFINITE );

            // Close process and thread handles. 
            CloseHandle( pi.hProcess );
            CloseHandle( pi.hThread );

Но если я использую путь с пробелом как код ниже, он не работает.

CreateProcess(_T("c:\\master installer\\ew3d.exe"),    // No module name (use command line)
                    _T("c:\\master installer\\ew3d.exe /qr"),//argv[1],        // Command line
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent environment block
                    NULL,           // Use parent starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 

И цитирование команды, например ниже, тоже не помогло

CreateProcess(_T("\"c:\\master installer\\ew3d.exe\""),    // No module name (use command line)
                    _T("\"c:\\master installer\\ew3d.exe\" /qr"),//argv[1],        // Command line
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent environment block
                    NULL,           // Use parent starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 

Каков правильный способ пройти по пути с пространством?

Ответ 1

Ваш третий фрагмент является правильным, не уверен, почему у вас проблемы. Здесь будет полезно иметь возвращаемое значение GetLastError(). Однако обратите внимание, что второй аргумент CreateProcess - это LPTSTR, а не LPCTSTR. Другими словами, Windows может писать обратно в строку. Довольно жутко, не так ли? Хватит рассуждать, возможно, вместо этого использовать ShellExecuteEx().

Ответ 2

В ответ на другой ответ, пример №3 - НЕ правильный.

Проблема заключается в том, что кавычки НЕ должны инкапсулировать путь к модулю, переданный как первый параметр CreateProcess. Однако кавычки ДОЛЖНЫ инкапсулировать arg0 (снова путь к модулю), который передается для командной строки (второй параметр CreateProcess).

Таким образом, правильное исполнение будет:

CreateProcess(_T("c:\\master installer\\ew3d.exe"),    
                    _T("\"c:\\master installer\\ew3d.exe\" /qr"),
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent environment block
                    NULL,           // Use parent starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 

Ответ 3

Вам не нужно указывать путь приложения как в первом, так и во втором аргументах. Согласно документации MSDN второй аргумент должен быть только аргументом командной строки, если вы укажете имя приложения в первом аргументе. В противном случае установите первый аргумент NULL, а затем во втором аргументе укажите имя приложения в кавычках, если оно содержит пробел. Не знаете, почему ваш последний список не работает.

Ответ 4

Документы неясны, но представляется возможным, что если вы включите пробел, вы должны разрешить параметру 2 определить полный путь.

Параметр lpApplicationName может быть НОЛЬ. В этом случае имя модуля должен быть первым белым маркер, ограниченный пространством в Строка lpCommandLine. Если вы используете длинное имя файла, содержащее коснитесь, используйте цитируемые строки, чтобы указать где имя файла заканчивается, и начинаются аргументы; в противном случае файл имя неоднозначно.

Вы пробовали эту вариацию?

CreateProcess(NULL,    // No module name (use command line)
              _T("\"c:\\master installer\\ew3d.exe\" /qr"),//argv[1],        // Command line
              NULL,           // Process handle not inheritable
              NULL,           // Thread handle not inheritable
              FALSE,          // Set handle inheritance to FALSE
              0,              // No creation flags
              NULL,           // Use parent environment block
              NULL,           // Use parent starting directory 
              &si,            // Pointer to STARTUPINFO structure
              &pi )           // Pointer to PROCESS_INFORMATION structure
             ) 

EDIT: для меня работало (dwError равно 0). Мой проект построен с многобайтовой кодировкой.

LPTSTR szCmdLine = _tcsdup(TEXT(
    "\"C:\\Program Files\\adobe\\Reader 8.0\\reader\\acrord32.exe\" /qr"));
CreateProcess(NULL,
              szCmdLine,
              NULL,           // Process handle not inheritable
              NULL,           // Thread handle not inheritable
              FALSE,          // Set handle inheritance to FALSE
              0,              // No creation flags
              NULL,           // Use parent environment block
              NULL,           // Use parent starting directory 
              &si,            // Pointer to STARTUPINFO structure
              &pi            // Pointer to PROCESS_INFORMATION structure
             );     // This works. Downcasting of pointer to members in general is fine.

DWORD error = GetLastError();

Ответ 5

Немного поздно на вечеринку. По какой-то причине я не могу проголосовать за преторианца, но он прав. У меня была одна и та же проблема, и NULLing Application Name сделал трюк. Я также попробовал путь в имени приложения и только параметры командной строки во втором аргументе, но безрезультатно.

Я нахожусь на Win7 x64.

CreateProcess (NULL, "\" Путь к exe\ "-x -y -z",...);

работает для меня.