加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何在Delphi中调用CreateProcess?

发布时间:2020-12-15 09:47:35 所属栏目:大数据 来源:网络整理
导读:参见英文答案 Access Violation in function CreateProcess in Delphi 2009????????????????????????????????????2个 根据 CreateProcess 和 the example from MSDN的文档,我试图拨打 CreateProcess : var commandLine: string; si: TStartupInfo; pi: TPro
参见英文答案 > Access Violation in function CreateProcess in Delphi 2009????????????????????????????????????2个
根据 CreateProcess和 the example from MSDN的文档,我试图拨打 CreateProcess

var
   commandLine: string;
   si: TStartupInfo;
   pi: TProcessInformation;
begin
   commandLine := 'C:WindowsSystem32cmd.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:

所以CreateProcess试图在我的unicode字符串的null终结符上乱涂乱画.如果CreateProcess将尝试修改命令行而不是使其更长,那么CreateProcess页面注释中存在一些争议.

我的弦完全有可能

C:WindowsSystem32cmd.exe

坐在只读数据部分.字符串本身的引用计数为-1:

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

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

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

commandLine := 'C:WindowsSystem32cmd.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?

其他人怎么称呼它?是否所有人都将字符串复制到字节缓冲区?

Bonus ShellExecute

他是你如何使用ShellExecute:

var
   shi: TShellExecuteInfo;

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

ShellExecuteEx(@shi);

解决方法

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

我认为他们已经在字符串转换中破坏了一些东西,因为我在Delphi XE中的旧代码在没有这种严格转换的情况下工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读