Гость
|
Добавлено: Чт Янв 15 2004 12:16 Заголовок сообщения: |
|
|
Параметры pszApplicationName и pszCommandLine
Эти параметры определяют имя исполняемого файла, которым будет пользоваться новый процесс, и командную строку, передаваемую этому процессу. Начнем cpszCom mandLine.
NOTE
Обратите внимание на тип параметра pszCommandLine: PTSTR. Он означает, что CreateProcess ожидает передачи адреса строки, которая не является констан той Дело в том, что CreateProcess в процессе своего выполнения модифици рует переданную командную строку, но перед возвратом управления восста навливает ее.
Это очень важно, если командная строка содержится в той части образа Вашего файла, которая предназначена только для чтения, возникнет ошибка доступа. Например, следующий код приведет к такой ошибке, потому что Visual С++ 6.0 поместит строку "NOTEPAD" в память только для чтения:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, TEXT("NOTEPAD"), NULL, NULL, FALSE, 0, NULL. NULL, &si, &pi);
Когда CreateProcess попытается модифицировать строку, произойдет ошиб ка доступа. (В прежних версиях Visual C++ эта строка была бы размещена в памяти для чтения и записи, и вызовы CreateProcess не приводили бы к ошиб кам доступа.)
Лучший способ решения этой проблемы — перед вызовом CreateProcess ко пировать константную строку во временный буфер:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szComrnandLine[] = TEXT("NOTEPAD");
CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULI, NULL, &si, &pi);
Возможно, Вас заинтересуют ключи /Gf и /GF компилятора Visual C++, ко торые исключают дублирование строк и запрещают их размещение в области только для чтения. (Также обратите внимание на ключ /ZI, который позволяет задействовать отладочную функцию Edit & Continue, поддерживаемую Visual Studio, и подразумевает активизацию ключа /GF.) В общем, лучшее, что може те сделать Вы, — использовать ключ /GF или создать временный буфер. А еще лучше, если Microsoft исправит функцию CreateProcess, чтобы та не морочила нам голову. Надеюсь, в следующей версии Windows так и будет.
Параметр pszCommandLme позволяет указать полную командную строку, исполь зуемую функцией CreateProcess при создании нового процесса. Разбирая эту строку, функция полагает, что первый компонент в ней представляет собой имя исполняе мого файла, который Вы хотите запустить. Если в имени этого файла не указано рас ширение, она считает его EXE. Далее функция приступает к поиску заданного файла и делает это в следующем порядке:
Каталог, содержащий ЕХЕ-файл вызывающего процесса.
Текущий каталог вызывающего процесса.
Системный каталог Windows.
Основной каталог Windows.
Каталоги, перечисленные в переменной окружения PATH.
Конечно, если в имени файла указан полный путь доступа, система сразу обраща ется туда и не просматривает эти каталоги. Найдя нужный исполняемый файл, она создает новый процесс и проецирует код и данные исполняемого файла на адресное пространство этого процесса Затем обращается к процедурам стартового кода из библиотеки С/С++. Тот в свою очередь, как уже говорилось, анализирует командную строку процесса и передает (w)WinMain адрес первого (за именем исполняемого фай ла) аргумента как pszCmdLine.
Все, о чем я сказал, произойдет, только если параметр pszApplicationName равен NULL (что и бывает в 99% случаев). Вместо NULL можио передать адрес строки с име нем исполняемого файла, который надо запустить. Однако тогда придется указать не только его имя, но и расширение, поскольку в этом случае имя не дополняется рас ширением EXE автоматически. CreateProcess предполагает, что файл находится в те кущем каталоге (если полный путь не задан). Если в текущем каталоге файла нет, функция не станет искать его в других каталогах, и на этом все закончится
Но даже при указанном в pszApplicationName имени файла CreateProcess все равно передает новому процессу содержимое параметра pszCommandLine как командную строку. Допустим, Вы вызвали CreateProcess так:
// размещаем строку пути в области памяти для чтения и записи
TCHAR szPath[] = TEXT("WORDPAD README.TXT");
// порождаем новый процесс
CreateProcess(TEXT("C:\\WINNr\\SYSrEM32\\NOTEPAD EXE"), szPath );
Система запускает Notepad, а в его командной строке мы видим "WORDPAD README.TXT". Странно, да? Но так уж она работает, эта функция CreateProcess. Упо мянутая возможность, которую обеспечивает пареметр pszApplicationName, на самом деле введена в CreateProcess для поддержки подсистемы POSIX в Windows 2000. |
|