ddablib / envvars

Environment Variables Unit
1 stars 2 forks source link

Encapsulate an environment block in a class #11

Open delphidabbler opened 2 years ago

delphidabbler commented 2 years ago

I really don't like how messy the TPJEnvironmentVars.CreateBlock method is.

It would be much better to encapsulate the whole messy business in a separate class and provide a Memory property that points to the required block.

TPJEnvironmentVars.CreateBlock could then be overridden to accept this new object as a parameter if it was thought necessary to retain such a method. The old TPJEnvironmentVars.CreateBlock could then be deprecated.

delphidabbler commented 2 years ago

Issue #12 proposes additional (class?) methods for this class.

delphidabbler commented 2 years ago

Possible prototype:

type
  TPJEnvironmentBlock = class
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddEnvVar(EV: TPJEnvironmentVar); overload;
    procedure AddEnvVar(Name, Value: string); overload;
    procedure AddEnvVars(EVS: TPJEnvironmentVarArray); overload;
    procedure AddEnvVars(SL: TStrings); overload;
    procedure Build;
    property IsUnicode: Boolean; default True; // read write
    property IncludeProcessEnvVars: Boolean; default True; // read write
    property IsDirty: Boolean; // read only
    property Memory: Pointer; // read only
    property Size: Cardinal;  // size in bytes - read only
  end;

Notes:

delphidabbler commented 2 years ago

There are limits on environment block sizes according to Microsoft on older operating systems. Here's what they say:

Windows Server 2003 and Windows XP: The maximum size of the environment block for the process is 32,767 characters. Starting with Windows Vista and Windows Server 2008, there is no technical limitation on the size of the environment block.

I'm assuming this limit also applies to Windows 2000.

As noted in a previous comment, the 32,767 also applies to ANSI blocks.

I can think of 2 ways to handle this limitation. Either detect the OS and raise an exception if the block is too large, or expose a function, say IsLargeBlock that returns true if the block size is greater than 32,767. If the 2nd approach is used then it's up to the user to check the OS if necessary.