Я вызвал другое приложение из своего основного приложения, используя API-интерфейс createprocess. Но другой процесс также нуждается в некоторых аргументах в качестве параметра.
Я создал процесс как:
BOOL ret= CreateProcess( NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL,&siStartInfo, &piProcInfo);
szCmdline является переменной, которая связывает полный путь приложения.
Любая идея, как передать аргумент с этим процессом.
Благодаря,
Вы можете создать строку, состоящую из имени программы + аргументов, подобных этому
wstring cmd;
cmd.assign(L"\"C:\\Program Files\\MyProgram.exe\" arg1 arg2 arg3 arg4");
if(!CreateProcess(NULL,(LPWSTR)cmd.c_str(),NULL,NULL,1,0,NULL,NULL,&si,&pi))
{
return -1;
}
У CreateProcess есть аргументы lpApplicationName и szCommandLine. Вы должны передать хотя бы один из аргументов. Однако вы должны пройти оба по соображениям безопасности.
lpApplicationName
- это имя исполняемого файла, который вы хотите запустить. szCommandLine
- это командная строка, которую вы хотите передать этому исполняемому файлу. Он должен включать исполняемый файл в качестве первого элемента. Это будет получено приложением в качестве аргумента WinMain
или будет восстановлено WinMain
GetCommandLine
(хотя система может добавлять полный путь, если он не указан). Для программ на C с использованием main
или wmain
он будет анализироваться CRT в аргументы.
Если вы передадите NULL
для lpApplicationName
, система попытается найти исполняемый файл в szCommandLine
и будет использовать это.
Если вы передадите NULL для szCommandLine
, система будет использовать lpApplicationName
для обоих.
Таким образом, командная строка - это командная строка. Если у вас есть аргументы для передачи команды, поместите их в командной строке.
Если lpApplicationName имеет значение NULL, первый токен, ограниченный пробелом в командной строке, указывает имя модуля. Если вы используете длинное имя файла, содержащее пробел, используйте цитированные строки, чтобы указать, где заканчивается имя файла и начинаются аргументы (см. Объяснение параметра lpApplicationName).
Предпочтительно передавать как lpApplicationName, так и szCommandLine, чтобы гарантировать, что система не ошибочно интерпретирует командную строку и запускается неправильный исполняемый файл. (Несколько лет назад был вызван класс проблем безопасности, вызванных этим).
Кроме того, при передаче как lpApplicationName, так и szCommandLine помните, что szCommandLine по-прежнему должен включать имя приложения в качестве первого аргумента.
Например, если ваша программа - C:\Program Files\My Application\Program.exe
а аргументы /the/arguments
, вы должны установить lpApplicationName в "C:\Program Files\My Application\Program.exe"
и установите szCmdline
в "C:\Program Files\My Application\Program.exe"/the/arguments
.
Каковы были проблемы безопасности?
Представьте себе, если кто-то создал файл "C:\Program Files\My.exe". Если вы опускаете кавычки, система интерпретирует C:\Program Files\My Application\Program.exe/the/arguments
как: C:\Program Files\My.exe Application\Program.exe/the/arguments
. И вы получите сюрприз. Этот трюк можно использовать для обмана администраторов в запущенных программах, которые они не хотели запускать, что является проблемой безопасности. Это не происходит, если вы передаете аргумент lpApplicationName.
Функция CreateProcess создает новый процесс, который выполняется независимо от процесса создания. Однако для простоты отношения называются отношениями родитель-потомок.
Первый параметр, lpApplicationName, может быть NULL, и в этом случае исполняемое имя должно быть в строке с пробелом, обозначенной lpCommandLine.
таким образом вы можете отправить несколько аргументов в API CreateProcess.
sprintf(exePath,"Project.exe %s %s \"%s\" \"%s\" \", appName,serverid,srjPath,caseName);
if( !CreateProcess( NULL, // No module name (use command line).
exePath, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
NORMAL_PRIORITY_CLASS,// No creation flags.
NULL, // Use parent environment block.
NULL, // Use parent starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
при восстановлении этих аргументов командной строки вы должны разборе этого аргумента и разделены меткой двойной кавычки, которой предшествует обратная косая черта, \", интерпретируется как буквальная двойная кавычка (").
для разбора аргумента командной строки посетите этот сайт: http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
и API-интерфейс creatprocess: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx
Используйте ShellExecute (Ex). Элемент управления намного проще, и поскольку у нас есть UAC, управление, как запускать процесс, проще.
С помощью ShellExecuteEx вы также получите обработчик процесса, если вам это нужно.
Просто мои 2 цента.
CreateProcess
: «Если этот параметр является постоянной строкой, функция может вызвать нарушение прав доступа». Всякий раз, когда вам нужен актерский состав, вы делаете это неправильно. Правдивая история.c_str()
возвращаетconst
указатель. Память, на которую он фактически указывает, не является доступной только для чтения. Приведение типа (const_cast
было бы лучше) просто для удаленияconst
-ness из указателя во время компиляции, посколькуCreateProcess()
не принимает указательconst
, но это не меняет того факта, что память все еще доступна для записи в время выполнения, поэтомуCreateProcess()
может безопасно писать в него без AV.