Windows API - путь CreateProcess () с пробелом - PullRequest
12 голосов
/ 29 октября 2010

Как передать путь с пробелом в функцию 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's environment block
                NULL,           // Use parent's 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's environment block
                    NULL,           // Use parent's 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's environment block
                    NULL,           // Use parent's starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 

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

Ответы [ 5 ]

19 голосов
/ 27 ноября 2013

В ответ на другой ответ, пример № 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's environment block
                    NULL,           // Use parent's starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 
4 голосов
/ 29 октября 2010

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

2 голосов
/ 29 октября 2010

Документы неясны, но кажется возможным, что если вы включите пробел, вы должны позволить параметру 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's environment block
              NULL,           // Use parent's starting directory 
              &si,            // Pointer to STARTUPINFO structure
              &pi )           // Pointer to PROCESS_INFORMATION structure
             ) 

РЕДАКТИРОВАТЬ: Следующее работало для меня (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's environment block
              NULL,           // Use parent's 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();
2 голосов
/ 29 октября 2010

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

1 голос
/ 11 февраля 2011

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

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

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

у меня работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...