Как использовать или расширить переменные среды в команде, созданной CreateProcess? - PullRequest
2 голосов
/ 27 марта 2012

В следующем коде используется CreateProcess для запуска команд с переменными среды.Здесь он пытается запустить notepad %APPDATA%\test.txt.

Если я запускаю notepad %APPDATA%\test.txt непосредственно в Windows' CMD,% APPDATA% будет расширен.Тем не менее, переменная среды не может быть расширена при выполнении CreateProcess.Не могли бы вы помочь прокомментировать причину и обходной путь?Любой комментарий будет оценен!

directly within cmd use 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.

1 Ответ

10 голосов
/ 27 марта 2012

Вызовите ExpandEnvironmentStrings , чтобы развернуть переменные среды.

Когда вы используете cmd.exe, он выполняет расширение для вас. CreateProcess этого не делает, поэтому вам нужно будет сделать это перед вызовом CreateProcess. В качестве альтернативы вы можете использовать ShellExecute, который будет расширять строки окружения.

Ваш текущий код не соответствует договору CreateProcess. Второй параметр должен быть указателем на модифицируемую память. С этим можно обойтись, если вы используете ANSI API, но при настройке Unicode ваш код может потерпеть неудачу. Передайте указатель на модифицируемую память, а не указатель на литерал. Если бы вы добавили вызов для расширения переменных среды, вы бы получили изменяемую строку.

Наконец, похоже, вы просто пытаетесь открыть текстовый файл. Зачем заставлять пользователя просматривать его в блокноте? Мой редактор по умолчанию для текстовых файлов не Блокнот. Я ненавидел бы любую программу, которая навязывала мне Блокнот. Вместо этого позвольте оболочке открыть файл в редакторе, выбранном пользователем. Вызовите ShellExecute, используйте «open» в качестве глагола и передайте имя текстового файла в качестве параметра имени файла. С другой стороны, возможно, вы знаете все это, и это только пример кода. Если это так, пожалуйста, просто проигнорируйте этот совет.

...