Иван Денисов писал(а):
использовать GetUserName или GetEnvironmentVariable
Лично я бы использовал второе. Потому что модуль для этого у меня уже есть : ).
Код:
MODULE Env;
TYPE
String* = POINTER TO ARRAY OF CHAR;
Hook* = POINTER TO ABSTRACT RECORD END;
VAR hook : Hook;
(* узнать значение переменной. name - название переменной *)
PROCEDURE (h: Hook) Get- (IN name : ARRAY OF CHAR) : String, NEW, ABSTRACT;
(* задать значение переменной. name - название переменной, val - значение *)
PROCEDURE (h: Hook) Set- (IN name, val : ARRAY OF CHAR), NEW, ABSTRACT;
PROCEDURE SetHook*(h : Hook);
BEGIN
hook := h
END SetHook;
PROCEDURE Get*(IN name : ARRAY OF CHAR) : String;
BEGIN
RETURN hook.Get(name)
END Get;
PROCEDURE Set*(IN name, val : ARRAY OF CHAR);
BEGIN
hook.Set(name, val)
END Set;
END Env.
Код:
MODULE HostEnv;
IMPORT Env, WinApi, SYSTEM;
CONST MaxLen = 32767;
TYPE
Hook = POINTER TO RECORD(Env.Hook)
ValueLen- : INTEGER
END;
SStr = POINTER TO ARRAY OF SHORTCHAR;
VAR
res : INTEGER;
hook : Hook;
PROCEDURE ToShort(IN str : ARRAY OF CHAR) : SStr;
VAR ret : SStr;
i, len : INTEGER;
BEGIN
i := 0; len := LEN(str$); NEW( ret, len + 1 );
WHILE i < len DO
ret[i] := SHORT( str[i] );
i := i + 1
END;
ret[i] := 0X;
RETURN ret
END ToShort;
PROCEDURE ToLong(str : SStr) : Env.String;
VAR ret : Env.String;
i, len : INTEGER;
BEGIN
i := 0; len := LEN(str$); NEW( ret, len + 1 );
WHILE i < len DO
ret[i] := LONG( str[i] );
i := i + 1
END;
ret[i] := 0X;
RETURN ret
END ToLong;
(* узнать значение переменной *)
PROCEDURE (h: Hook) Get(IN name : ARRAY OF CHAR) : Env.String;
VAR sname, sval : SStr;
len : INTEGER;
ret : Env.String;
BEGIN
sname := ToShort(name);
len := 256;
NEW( sval, len );
res := WinApi.GetEnvironmentVariable(sname^, sval^, len);
ret := ToLong(sval);
RETURN ret
END Get;
(* задать значение переменной *)
PROCEDURE (h: Hook) Set(IN name, val: ARRAY OF CHAR);
VAR sname, sval : POINTER TO ARRAY OF SHORTCHAR;
BEGIN
sname := ToShort(name);
sval := ToShort(val);
res := WinApi.SetEnvironmentVariable(sname^, sval^)
END Set;
(* Задать размер значения переменной.
Используется при получении значения из ОС.
Если возвращено значение больше заданного размера, то хвост отсекается. *)
PROCEDURE (h: Hook) SetValLen(i : INTEGER), NEW;
BEGIN
(* тихое игнорирование приказа. Нужно что-то придумать *)
IF (i >= 0) & (i < MaxLen) THEN
h.ValueLen := i + 1 (* учитываем нолик в конце строки *)
END
END SetValLen;
PROCEDURE Init*(len : INTEGER);
BEGIN
NEW( hook );
hook.ValueLen := len;
Env.SetHook(hook)
END Init;
BEGIN
Init(256)
END HostEnv.