Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A process launched by Delphi IDE's "Run without debugging" inherits environment variables of IDE

Tags:

delphi

I am writing a Windows GUI application that attempt to invoke Apache ANT script. The ANT script will build and pack a Delphi project group into a final setup.exe. The ANT script build Delphi 2007/2010 and Delphi XE application.

My ANT GUI application is compiled and built by Delphi XE. When I use "Run without Debugging" in Delphi XE to run the application, the application doesn't work correctly with ANT script. The ANT script doesn't build the application where the DCUs, BPLs and EXEs doensn't compiled into folder I expected.

However, if I launch my GUI application in Windows Explorer, the ANT script build the application correctly> All DCUs, BPLs and EXEs were built and keep into folder I assigned.

After debug the GUI application, I found that application run with Delphi's "Run without debugging" will inherit environment variables from Delphi IDE. Here is how I extract the environment variables:

function GetAllEnvVars(const Vars: TStrings): Integer;
var
  PEnvVars: PChar;    // pointer to start of environment block
  PEnvEntry: PChar;   // pointer to an env string in block
begin
  // Clear the list
  if Assigned(Vars) then
    Vars.Clear;
  // Get reference to environment block for this process
  PEnvVars := GetEnvironmentStrings;
  if PEnvVars <> nil then
  begin
    // We have a block: extract strings from it
    // Env strings are #0 separated and list ends with #0#0
    PEnvEntry := PEnvVars;
    try
      while PEnvEntry^ <> #0 do
      begin
        if Assigned(Vars) then
          Vars.Add(PEnvEntry);
        Inc(PEnvEntry, StrLen(PEnvEntry) + 1);
      end;
      // Calculate length of block
      Result := (PEnvEntry - PEnvVars) + 1;
    finally
      // Dispose of the memory block
      Windows.FreeEnvironmentStrings(PEnvVars);
    end;
  end
  else
    // No block => zero length
    Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetAllEnvVars(Memo1.Lines);
end;

This is a list of environment variables for a process launched by Delphi XE's "Run without Debugging":

ActiveHostApplication=
ActiveProjectModule=
ALLUSERSPROFILE=C:\ProgramData
ANT_HOME=C:\Components\Components.d11\build.tool\apache-ant-1.7.1
ANT_OPTS=-Xmx512m
APPDATA=C:\Users\coder\AppData\Roaming
AQtime7_Product_Path=C:\Program Files (x86)\Automated QA\AQtime 7\Bin\
BDS=c:\program files (x86)\embarcadero\rad studio\8.0
BDSAppDataBaseDir=BDS
BDSBIN=c:\program files (x86)\embarcadero\rad studio\8.0\bin
BDSCOMMONDIR=C:\Users\Public\Documents\RAD Studio\8.0
BDSINCLUDE=c:\program files (x86)\embarcadero\rad studio\8.0\include
BDSLIB=c:\program files (x86)\embarcadero\rad studio\8.0\lib
BDSPROJECTSDIR=C:\Users\coder\Documents\RAD Studio\Projects
BDSUSERDIR=C:\Users\coder\Documents\RAD Studio\8.0
CG_BOOST_ROOT=C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\include\boost_1_39
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=OBSERVER
ComSpec=C:\Windows\system32\cmd.exe
DELPHI=c:\program files (x86)\embarcadero\rad studio\8.0

And this is a list of environment variables for a process launched by Windows Explorer:

ALLUSERSPROFILE=C:\ProgramData
ANT_HOME=C:\Components\Components.d11\build.tool\apache-ant-1.7.1
ANT_OPTS=-Xmx512m
APPDATA=C:\Users\coder\AppData\Roaming
BDSCOMMONDIR=C:\Users\Public\Documents\RAD Studio\5.0
CG_BOOST_ROOT=C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\include\boost_1_39
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=OBSERVER
ComSpec=C:\Windows\system32\cmd.exe
FP_NO_HOST_CHECK=NO

Compare 2 list of environment variables, you may notice there are few variables like BDSINCLUDE and BDSBIN doesn't exist in process launched by Windows Shell. Those environment variables from Delphi XE's IDE has affected the ANT script that build the Delphi 2007/2010 application. My problem should solve if those Delphi IDE environment variables doesn't shown in the process.

Does anyone has ideas if it is possible to launch process (either Run with or without debugging) from Delphi IDE that do not inherit environment variables from Delphi IDE?

like image 613
Chau Chee Yang Avatar asked Dec 08 '10 02:12

Chau Chee Yang


2 Answers

A program inherits the environment of the process that starts it. There's no reason for Delphi to clear the environment anyway; programs should be prepared for any arbitrary environments they get started with.

If your program fails when certain environment variables are set, then you need to make your program address it. You can delete entries from your program's environment with SetEnvironmentVariable; pass a null pointer as the second parameter. Or you can figure out why your program is so sensitive to seemingly unrelated variables and change it.

You can also generate a new environment and use it when your program starts Ant. Pass it as the seventh parameter to CreateProcess. Set or remove whatever values you want.

like image 52
Rob Kennedy Avatar answered Nov 15 '22 04:11

Rob Kennedy


Thanks for Rob Kennedy hints. I tried to use SetEnvironmentVariable to nil variable one by one. One of environment variable Platform=Win32 imposed by Delphi IDE caused the problem.

SetEnvironmentVariable('Platform', nil);

Setting the Platform to nil make ANT build works as expected.

like image 39
Chau Chee Yang Avatar answered Nov 15 '22 04:11

Chau Chee Yang