gpt4 book ai didi

delphi - Delphi中如何调用CreateProcess?

转载 作者:行者123 更新时间:2023-12-03 15:12:51 24 4
gpt4 key购买 nike

遵循 CreateProcess 的文档,和the example from MSDN ,我正在尝试调用 CreateProcess :

var
commandLine: string;
si: TStartupInfo;
pi: TProcessInformation;
begin
commandLine := 'C:\Windows\System32\cmd.exe';

si := Default(TStartupInfo);
si.cb := sizeof(si);

CreateProcess(
PChar(nil), //no module name (use command line)
PChar(commandLine), //Command Line
nil, //Process handle not inheritable
nil, //Thread handle not inheritable
False, //Don't inherit handles
0, //No creation flags
nil, //Use parent's environment block
PChar(nil), //Use parent's starting directory
si, //Startup Info
pi //Process Info
);

调用因访问冲突而崩溃:

Exception EAccessViolation in module kernel32.dll at 0003B77B.
Access violation at address 7671B77B in module 'kernel32.dll'. Write of address 00B47EA6.

现在我明白为什么它会崩溃,但我不明白为什么 it isn't crashing for the sample code on MSDN ,我也不明白why it wasn't failing for you David .

CreateProcess 的文档表示如果第一个参数为 null(如我的示例、MSDN 示例和其他示例中所示),则 CreateProcess修改commandLine论据:

lpCommandLine [in, out, optional]

...

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

当我查看访问冲突时,它正在尝试写入地址 0x00B47EA6 :

enter image description here

所以CreateProcess正在尝试在我的 unicode 字符串的空终止符上乱写。 CreateProcess 中有一些争论。页面评论如果 CreateProcess将尝试修改命令行而不是使其更长。

我的字符串完全有可能

C:\Windows\System32\cmd.exe

位于只读数据部分。该字符串本身的引用计数为 -1 :

enter image description here

当常量字符串来自常量时,就会发生这种情况。

我可以通过将字符串复制到缓冲区来测试这一点:

var
commandLine: string;
si: TStartupInfo;
pi: TProcessInformation;
l: Integer;
buffer: TByteDynArray;

commandLine := 'C:\Windows\System32\cmd.exe';

//Copy to writable buffer (including null terminator)
l := (Length(commandLine)+1)*sizeof(Char);
SetLength(buffer, l);
Move(commandLine[1], buffer[0], l);

si := Default(TStartupInfo);
si.cb := sizeof(si);

if not CreateProcess(
PChar(nil), //no module name (use command line)
// PChar(commandLine), //Command Line
@buffer[0],
nil, //Process handle not inheritable
nil, //Thread handle not inheritable
False, //Don't inherit handles
0, //No creation flags
nil, //Use parent's environment block
PChar(nil), //Use parent's starting directory
si, //Startup Info
{var}pi //Process Info
);

并且成功了。

因此,在提出我的问题并进行研究之后,我已经回答了我自己的问题。但我仍然想知道处理这个问题的正确方法是什么

How to call CreateProcess in Delphi?

其他人都怎么调用它?其他人都将字符串复制到字节缓冲区吗?

奖金 ShellExecute

他就是你使用ShellExecute的方式:

var
shi: TShellExecuteInfo;

shi := Default(TShellExecuteInfo);
shi.cbSize := SizeOf(TShellExecuteInfo);
shi.lpFile := PChar(commandLine);
shi.nShow := SW_SHOWNORMAL;

ShellExecuteEx(@shi);

最佳答案

您可以将 PChar(commandLine) 替换为 PChar(WideString(commandLine))。这在 Delphi XE6 中对我有用。

我想他们已经破坏了字符串转换中的某些内容,因为我在 Delphi XE 中的旧代码无需如此严格的转换即可工作。

关于delphi - Delphi中如何调用CreateProcess?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26678429/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com