windows - Sådan bruger eller udvider du miljøvariabler i en kommando, der er etableret af CreateProcess?

Indlæg af Hanne Mølgaard Plasc

Problem



Følgende kode benytter CreateProcess til at køre kommandoer med miljøvariabler. Her forsøger den at køre notepad \%APPDATA\% est.txt.


Hvis jeg kører notepad \%APPDATA\% est.txt direkte inden for Windows' CMD, vil\% APPDATA\% blive udvidet. Miljøvariablen kan dog ikke udvides, når den udføres af CreateProcess. Kan du hjælpe med at kommentere årsagen og løsningen? Enhver kommentar vil blive værdsat!


direkte inden for cmd
brug 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\%	est.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.

Bedste reference


Ring til ExpandEnvironmentStrings for at udvide miljøvariabler. [7]


Når du bruger cmd.exe, udfører den ekspansionen for dig. CreateProcess gør det ikke, så du skal gøre det, før du kalder CreateProcess. Alternativt kan du bruge ShellExecute, som vil udvide miljøstrengene.


Din nuværende kode opfylder ikke kontrakten i CreateProcess. Den anden parameter skal være en pointer til modificerbar hukommelse. Du kan komme væk med dette, hvis du bruger ANSI API, men når du targetting Unicode du kode er i stand til at mislykkes. Videresend en peger til modificerbar hukommelse frem for en peger til en bogstav. Hvis du tilføjede et opkald for at udvide miljøvariablerne, ville du ende med en modificerbar streng.


Endelig ser det ud til, at du bare forsøger at åbne en tekstfil. Hvorfor tvinge brugeren til at se det i Notesblok? Min standard editor til tekstfiler er ikke Notesblok. Jeg dræber ethvert program, der tvunget Notepad på mig. I stedet skal shell'en åbne filen i brugerens foretrukne editor. Ring ShellExecute, brug 'open' som verben og send tekstfilnavnet som filnavn parameter. På den anden side, måske ved du alt dette, og dette er kun eksempelkode. Hvis ja, vær så snill at ignorere dette råd.