Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   gelöst: CreateProcess und "Environment-Block" (https://www.delphipraxis.net/217326-geloest-createprocess-und-environment-block.html)

TSHObject 10. Jun 2025 20:33


gelöst: CreateProcess und "Environment-Block"
 
Hallo zusammen,

ich komm nicht mehr weiter.
Es geht um CreateProcess und den Parameter "Environment-Block".

Meine Anwendung startet mittels "CreateProcess" die msbuild.exe.

Es funktioniert, wenn ich meine Anwendung aus der IDE starte.
Es funktioniert NICHT, wenn ich meine Anwendung direkt aus einem Windows-Explorer starte. Es kommt der Fehler
C:\projects\dpt\unittests\example_data\project_msb uild_win32_debug\Project_msbuild_win32_debug.dproj : error MSB4057: Das Ziel "build" ist im Projekt nicht vorhanden.


Wenn ich eine Batch-Datei erstelle und diese direkt aus dem Windows-Explorer starte, dann funktioniert es auch.
Code:
ECHO ***************************************************************************
ECHO *** Batch-file generated by DelphiPackageTool (DPT) ***********************
ECHO ***************************************************************************
SET BDS=C:\Program Files (x86)\Embarcadero\Studio\23.0\
SET PROJECTGROUPROOT=C:\projects\dpt\unittests\example_data\
ECHO ***************************************************************************
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "%PROJECTGROUPROOT%project_msbuild_win32_debug\Project_msbuild_win32_debug.dproj" /t:build /p:config="Debug" /p:platform="Win32" /p:target="Deploy"

Pause
Wenn ich die Zeile "SET BDS=C:\Program Files (x86)\Embarcadero\Studio\23.0\" in der Batch-Datei weglasse, dann kommt
auch die Fehlermeldung
C:\projects\dpt\unittests\example_data\project_msb uild_win32_debug\Project_msbuild_win32_debug.dproj : error MSB4057: Das Ziel "build" ist im Projekt nicht vorhanden.

Daraus schliesse ich, dass man irgendwie im Parameter "Enviornment" der Methode "CreateProcess" die Information "SET BDS=C:\Program Files (x86)\Embarcadero\Studio\23.0\" mitgeben muss.
Aber wie?

Ich bin um jeden Hinweis dankbar.

Gruss

Olli73 10. Jun 2025 21:18

AW: CreateProcess und "Environment-Block"
 
Am einfachsten ist es, vor dem Aufruf von CreateProcess die EnvironmentVariablen per "SetEnvironmentVariable(...)" zu setzen.

Wenn du lieber den Parameter Environment von CreateProcess nutzen willst, brauchst du sowas:

Delphi-Quellcode:
var
  Env: AnsiString; //Oder String, dann muss "dwCreationFlags" aber "CREATE_UNICODE_ENVIRONMENT" enthalten

Env := 'BDS=C:\Program Files (x86)\Embarcadero\Studio\23.0\' + #0 + 'PROJECTGROUPROOT=C:\projects\dpt\unittests\example_data\' + #0#0;
Und im CreateProcess dann als Parameter Environment angeben: @Env[1]

jaenicke 11. Jun 2025 05:05

AW: CreateProcess und "Environment-Block"
 
Du kennst aber die rsvars.bat? Die liegt im bin-Ordner von Delphi. Es sollte reichen, wenn du die in der Batchdatei vor dem Aufruf an msbuild aufrufst. Die setzt dann die nötigen Werte.

TSHObject 11. Jun 2025 06:19

AW: CreateProcess und "Environment-Block"
 
Vielen Dank für eueren Input.

Meine Lösung sieht nun so aus:

Delphi-Quellcode:
function SetEnvironmentsVars(const Vars: TStrings): Boolean;
var
i: integer;
_line:string;
_Name:string;
_Value:string;
_EqualsPos:integer;
_DoublePointPos:integer;
_prefix:string;
_ErrorMsg:string;
_ProblemCount:integer;
begin
  _ProblemCount:=0;
  for i := 0 to Vars.Count - 1 do begin
    _line := Vars[i];
    _EqualsPos := Pos('=', _line);
    if _EqualsPos=-1 then begin
      inc(_ProblemCount);
      _ErrorMsg:=format('SetEnvironmentsVars: The environment statement <%s> does not contain the character "=". Ignore this line.',[_line]);
      OutputDebugString(PChar(_ErrorMsg));
      continue;
    end;

    if _EqualsPos=1 then begin
      _DoublePointPos := Pos(':', _line);
      _prefix:=Copy(_line,1,_DoublePointPos);
      delete(_Line,1,_DoublePointPos);
    end
    else _prefix:='';

    _Name := _prefix+_Line.Substring(0,_EqualsPos-1);
    _Value := _Line.Substring(_EqualsPos);
    if not SetEnvironmentVariable(PChar(_Name), PChar(_Value)) then begin
      inc(_ProblemCount);
      _ErrorMsg:=format('SetEnvironmentsVars: Could not set environment variable <%s=%s>. <%s>.',[_Name,_Value,SysErrorMessage(GetLastError)]);
    end;
  end;
  result:=(_ProblemCount=0);
end;

himitsu 11. Jun 2025 20:09

AW: gelöst: CreateProcess und "Environment-Block"
 
Die IDE vererbt ihre Umgebungsvariablen an Kindprozesse (zumindest 32 Bit im InlineDebugger)
Und da kann man in den IDE-Optionen auch eigene Umgebungsvariablen hinzufügen.

Bei 64 Bit oder RemoteDebugger/PAServer sieht die Sache wieder anders aus.

In der rsvars.bat sind aber nur die Basis-Variablen der IDE drin,
der Rest der Umgebungsvariablen, vor allem der Selbstdefinierten, ist in der environment.proj zu finden, welche über die Projekt-DPROJ gelinkt wird (falls es keinen Fehler beim Laden gibt, da dort die Fehlerbehandlung fehlt).

https://www.delphipraxis.net/216739-...-aufrufen.html
https://www.delphipraxis.net/203455-...tch-datei.html



PS: Wenn man sein aktuelles Environment erweitern will, ohne "alles" neu zusammenzubauen, kann man auch MSDN-Library durchsuchenGetEnvironmentStrings verwenden und die Ausgabe anpassen.
Oder bei sich selbst vorher das eigene Environment ändern und GetEnvironmentStrings direkt als Environment für's CreateProcess nutzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz