How to use or expand environment variables in a command instantiated by CreateProcess?

帅比萌擦擦* 提交于 2019-12-06 10:20:13

问题


The following code utilizes CreateProcess to run commands with environmental variables. Here, it tries to run notepad %APPDATA%\test.txt.

If I run notepad %APPDATA%\test.txt directly within Windows' CMD, %APPDATA% will be expanded. However, the environmental variable can not be expanded when executed by CreateProcess. Could you help to comment on the reason and the workaround? Any comment will be appreciated!

    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.

回答1:


Call ExpandEnvironmentStrings to expand environment variables.

When you use cmd.exe, it performs the expansion for you. CreateProcess does not so you will need to do it before calling CreateProcess. Alternatively you could use ShellExecute which will expand environment strings.

Your current code does not meet the contract of CreateProcess. The second parameter must be a pointer to modifiable memory. You can get away with this if you are using the ANSI API but when targetting Unicode you code is liable to fail. Pass a pointer to modifiable memory rather than a pointer to a literal. If you added a call to expand the environment variables then you would end up with a modifiable string.

Finally, it looks like you are just trying to open a text file. Why force the user to view it in Notepad? My default editor for text files is not Notepad. I'd loath any program that forced Notepad on me. Instead let the shell open the file in the user's preferred editor. Call ShellExecute, use 'open' as the verb and pass the text file name as the file name parameter. On the other hand, perhaps you know all this and this is just example code. If so, please just ignore this advice.



来源:https://stackoverflow.com/questions/9890746/how-to-use-or-expand-environment-variables-in-a-command-instantiated-by-createpr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!