Ошибки доступа при использовании CreateProcess в Delphi: причины и решения
Вопрос использования функции CreateProcess в Delphi может вызвать затруднения, так как существует нюанс, связанный с модификацией строки команды. В документации по CreateProcess указано, что если первый параметр функции - null, то CreateProcess может модифицировать строку commandLine. Это означает, что строка должна быть изменяемой, иначе возможны ошибки доступа.
Пример кода, вызывающего ошибку:
var
commandLine: string;
si: TStartupInfo;
pi: TProcessInformation;
begin
commandLine := 'C:\Windows\System32\cmd.exe';
si := Default(TStartupInfo);
si.cb := SizeOf(si);
CreateProcess(
nil,
PChar(commandLine),
nil,
nil,
False,
0,
nil,
nil,
si,
pi
);
При выполнении этого кода возникает ошибка доступа, поскольку строка commandLine может находиться в разделе только для чтения, например, в разделе константных строк.
Решение проблемы:
Чтобы избежать ошибок доступа, необходимо скопировать строку в изменяемый буфер. Это можно сделать следующим образом:
var
commandLine: string;
si: TStartupInfo;
pi: TProcessInformation;
l: Integer;
buffer: TCharArray;
begin
commandLine := 'C:\Windows\System32\cmd.exe';
l := (Length(commandLine) + 1) * SizeOf(Char);
SetLength(buffer, l);
Move(commandLine[1], buffer[0], l);
si := Default(TStartupInfo);
si.cb := SizeOf(si);
CreateProcess(
nil,
@buffer[0],
nil,
nil,
False,
0,
nil,
nil,
si,
pi
);
Используя функцию UniqueString можно также обеспечить изменяемость строки:
var
commandLine: UniqueString;
begin
commandLine := 'C:\Windows\System32\cmd.exe';
// Создание процесса с использованием переменной commandLine
end
Альтернативный способ:
Также можно использовать функцию ShellExecuteEx, которая может быть более удобной для некоторых задач:
var
shi: TShellExecuteInfo;
begin
shi := Default(TShellExecuteInfo);
shi.cbSize := SizeOf(TShellExecuteInfo);
shi.lpFile := PChar(commandLine);
shi.nShow := SW_SHOWNORMAL;
ShellExecuteEx(@shi);
end
Заключение:
При использовании CreateProcess важно понимать, что строка, передаваемая в функцию, должна быть изменяемой. Это можно обеспечить, скопировав строку в изменяемый буфер или используя функцию UniqueString. Если же вы предпочитаете избегать потенциальных проблем с CreateProcess, можно использовать альтернативный подход с ShellExecuteEx.
Описание контекста: Вопрос связан с ошибками доступа при использовании функции `CreateProcess` в Delphi, их причинами и методами решения, включая изменение строки команды и использование альтернативных методов, таких как `ShellExecuteEx`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.