如何在CreateProcess实例化的命令中使用或扩展环境变量?

SOU*_*ser 2 windows delphi winapi createprocess environment-variables

以下代码CreateProcess用于运行带有环境变量的命令.在这里,它试图运行notepad %APPDATA%\test.txt.

如果我notepad %APPDATA%\test.txt直接在其中运行Windows' CMD,%APPDATA%将被扩展.但是,执行时无法扩展环境变量CreateProcess.你能帮忙评论原因和解决方法吗?任何评论将不胜感激!

直接在cmd内 使用CreateProcess

    program TestConsole2;

    {$APPTYPE CONSOLE}

    uses
      Windows, SysUtils;

    var
      I: Integer;
      ProgramName: String;
      StartInfo  : TStartupInfo;
      ProcInfo   : TProcessInformation;
      CreateOK   : Boolean;
    begin
      try

        FillChar(StartInfo, SizeOf(StartInfo), #0);
        FillChar(ProcInfo, SizeOf(ProcInfo), #0);
        StartInfo.cb := SizeOf(StartInfo);

        ProgramName := 'NOTEPAD %APPDATA%\test.txt';
        CreateOK := CreateProcess(
          nil, PChar(ProgramName), nil, nil, True, 0, nil, nil, StartInfo, ProcInfo);
        if CreateOK then WaitForSingleObject(ProcInfo.hProcess, INFINITE);

        Readln(ProgramName);

      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 10

调用ExpandEnvironmentStrings以扩展环境变量.

使用cmd.exe时,它会为您执行扩展.CreateProcess没有,所以在调用CreateProcess之前你需要这样做.或者,您可以使用ShellExecute来扩展环境字符串.

您当前的代码不符合CreateProcess的合同.第二个参数必须是指向可修改内存的指针.如果您使用的是ANSI API,则可以使用此API,但在定位Unicode时,您的代码可能会失败.将指针传递给可修改的内存,而不是指向文字的指针.如果添加了一个调用来扩展环境变量,那么最终会得到一个可修改的字符串.

最后,看起来你只是想打开一个文本文件.为什么强制用户在记事本中查看它?我的文本文件的默认编辑器不是记事本.我不喜欢任何强迫记事本的程序.而是让shell在用户首选编辑器中打开文件.调用ShellExecute,使用'open'作为动词,并将文本文件名作为文件名参数传递.另一方面,也许你知道这一切,这只是示例代码.如果是这样,请忽略这个建议.