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",...);
работает для меня.