Vanmorgen had ik het weer eens nodig: routines om een environment block te kunnen schrijven omdat ik bij createprocess het sub process een eigen omgeving wilde meegeven. (Meestal zie je dat niet en wordt er nil voor het environment block meegegeven).
Toch is het erg handig, bijvoorbeeld om verschillende versies van DCC32 te starten met verschillende paden of om een redirected console een eigen omgeving mee te geven.
Aangezien ik dit soort dingen uit mijn hoofd opschrijf was ik al jaren te lui om het echt netjes te doen of een echt nette manier te googlen.
Dat laatste deed ik vannacht, maar ik kon niks vinden dat aan mijn eisen voldeed. Hier een korte unit die het in mijn optiek wel netjes en begrijpelijk doet:
Code:
unit NLDReadWriteEnvironmentBlock;
// Auteur Thaddy de Koning
// Freeware
interface
uses windows, classes, SysUtils;
const
// Terminator gedefinieerd als typed const
// (Zoadat het een memory reference heeft)
NullChar:Char = #0;
type
TEnvironmentBlockReader = class(Tstringlist)
public
constructor Create;
end;
TEnvironmentBlockWriter = class(TStringStream)
private
FClosed:Boolean;
function GetBlockPtr: PAnsiChar;
protected
procedure Close;
public
procedure Add(const aValue:string);overload;
procedure Add(const aToken,aValue:string);overload;
Property Block:PAnsiChar read GetBlockPtr;
end;
implementation
{ TEnvironmentBlockWriter }
// Is het blok gesloten?
// Zoja, ga een positie terug
// Schrijf de string
// Schrijf terminating #0
procedure TEnvironmentBlockWriter.Add(const aValue: string);
begin
If FClosed then
begin
Seek(-1,soFromEnd);
Fclosed :=False;
end;
WriteString(aValue);
Write(NullChar,1);
end;
procedure TEnvironmentBlockWriter.Add(const aToken, aValue: string);
begin
Add(aToken+'='+aValue);
end;
// Block afsluiten door een extra #0 te schrijven, als gespecificeerd
procedure TEnvironmentBlockWriter.Close;
begin
if not FClosed then
begin
write(NullChar,1);
FClosed := True;
end;
end;
// Als we het block uitlezen nemen we aan dat het gesloten is!
function TEnvironmentBlockWriter.GetBlockPtr: PAnsiChar;
begin
Close;
Result := PChar(DataString);
end;
{ TEnvironmentBlockReader }
constructor TEnvironmentBlockReader.Create;
var
FBlock,
StrPtr:PChar;
begin
inherited;
FBlock :=GetEnvironmentStrings;
if FBlock <> nil then
try
StrPtr := FBlock;
repeat
Add(StrPtr);
inc(StrPtr, Succ(StrLen(StrPtr)));
until StrPtr^= #0;
finally
FreeEnvironmentStrings(Fblock);
end;
end;
end.
Schrijven kan op twee manieren:
Als 'token=value' paren of direct als string.
Je geeft aan bijv. CreateProcess simpel de TEnvironmentBlockWriter.Block parameter mee.
Lezen kan met alle stringlist methoden.
Bookmarks