Ian*_*oyd 5 delphi winapi delphi-xe6
根据MSDN的文档CreateProcess和示例,我正在尝试调用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
);
Run Code Online (Sandbox Code Playgroud)
呼叫因访问冲突而崩溃:
在0003B77B模块kernel32.dll中的EAccessViolation异常.
模块'kernel32.dll'中地址为7671B77B的访问冲突.写地址00B47EA6.
现在我理解为什么它会让我崩溃,但我不明白为什么它不会崩溃MSDN上的示例代码,我也不明白为什么它没有为你失败大卫.
对于文件CreateProcess说,如果第一个参数为空(因为它是在我的例子,在MSDN例子,其他的例子),然后CreateProcess将修改的commandLine参数:
lpCommandLine [in,out,optional]
...
此函数的Unicode版本CreateProcessW可以修改此字符串的内容.因此,此参数不能是只读内存的指针(例如const变量或文字字符串).如果此参数是常量字符串,则该函数可能会导致访问冲突.
当我查看访问冲突时,它正在尝试写入地址0x00B47EA6:

所以CreateProcess试图乱写我的unicode字符串的null终止符.CreateProcess如果CreateProcess将尝试修改命令行而不是延长命令行,则页面注释中存在一些争议.
我的弦完全有可能
C:\ WINDOWS\SYSTEM32\CMD.EXE
坐在只读数据部分.字符串本身的引用计数为-1:

当常量字符串来自常量时会发生这种情况.
我可以通过将字符串复制到缓冲区来测试它:
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
);
Run Code Online (Sandbox Code Playgroud)
这成功了.
所以在创作我的问题并研究之后,我已经回答了我自己的问题.但我仍然想知道处理这个问题的正确方法是什么
如何在Delphi中调用CreateProcess?
其他人怎么称呼它?是否所有人都将字符串复制到字节缓冲区?
ShellExecute他是你如何使用ShellExecute:
var
shi: TShellExecuteInfo;
shi := Default(TShellExecuteInfo);
shi.cbSize := SizeOf(TShellExecuteInfo);
shi.lpFile := PChar(commandLine);
shi.nShow := SW_SHOWNORMAL;
ShellExecuteEx(@shi);
Run Code Online (Sandbox Code Playgroud)
小智 3
您可以将 PChar(commandLine) 替换为 PChar(WideString(commandLine))。这在 Delphi XE6 中对我有用。
我想他们已经破坏了字符串转换中的某些内容,因为我在 Delphi XE 中的旧代码无需如此严格的转换即可工作。
| 归档时间: |
|
| 查看次数: |
14160 次 |
| 最近记录: |