> -- Иван Денисов писал(а):
> использовать 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.
```
