OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 04 Июль, 2020 03:06

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
СообщениеДобавлено: Понедельник, 22 Апрель, 2013 05:30 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2757
Не могу понять как корректно в следующем случае получить данные от функции WinApi. Помогите, пожалуйста. Задача: взять из реестра данные об окружении пользователя.

Код:
MODULE DiaRegTest;

   IMPORT  SYSTEM, Log, WinApi, HostRegistry;
   
   TYPE
      StringPtr = POINTER TO ARRAY [untagged] OF CHAR;
   
   PROCEDURE Home*;
      VAR r, len, type, res: INTEGER;  adr: SHORTCHAR;  i: INTEGER;
      str2, data: StringPtr; hndl: WinApi.HANDLE;
   BEGIN
      res := WinApi.RegOpenKeyW(WinApi.HKEY_CURRENT_USER, "Volatile Environment", hndl);
      len := 1024;
      res := WinApi.RegQueryValueExW(hndl, "USERNAME", NIL, type, adr, len);
      
      Log.String("res: "); Log.Int(res);
      Log.String(" type: "); Log.Int(type);
      Log.String(" len: "); Log.Int(len);Гипотеза
      Log.Ln;
      
      Log.String("data adr: "); Log.Int(SYSTEM.ADR(adr));
      Log.Ln;
      
      str2 := SYSTEM.VAL(StringPtr, SYSTEM.ADR(adr));
      Log.String(str2$); Log.Ln;
      
   END Home;

END DiaRegTest.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Апрель, 2013 07:13 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2347
Откуда: Россия, Томск
Встречный вопрос: не лучше ли будет GetUserName или GetEnvironmentVariable?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Апрель, 2013 07:14 

Зарегистрирован: Четверг, 12 Июнь, 2008 17:30
Сообщения: 37
test this:

Код:
MODULE DiaRegTest;
   
   IMPORT SYSTEM, Log, WinApi;

   PROCEDURE Home* ;
      VAR
         len, type, res: INTEGER;
         data: ARRAY 512 OF CHAR;
         hkey: WinApi.HANDLE;
   BEGIN
      res := WinApi.RegOpenKeyW(WinApi.HKEY_CURRENT_USER, "Volatile Environment", hkey);
      IF res = 0 THEN
         len := LEN(data) * 2;
         res := WinApi.RegQueryValueExW(hkey, "USERNAME", NIL, type, SYSTEM.VAL(SHORTCHAR, data[0]), len);
         Log.String("res: "); Log.Int(res); Log.Tab;
         Log.String(" type: "); Log.Int(type); Log.Tab; Log.String(" len: "); Log.Int(len DIV 2);Log.Ln;
         Log.String('data:'); Log.String(data); Log.Ln;
         res := WinApi.RegCloseKey(hkey);
      ELSE
         Log.String('open key error!'); Log.Tab; Log.Int(res); Log.Ln;
      END;
   END Home;

END DiaRegTest.




Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Апрель, 2013 15:02 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2757
Александр Ильин писал(а):
Встречный вопрос: не лучше ли будет GetUserName или GetEnvironmentVariable?
Не могу ответить, что лучше (не спец по WinApi). Этот проще в использовании. Хотя тот метод более общий. Теперь будет выбор :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Апрель, 2013 16:25 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2757
maliya писал(а):
test this:
Thanks a lot! It works!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 23 Апрель, 2013 22:50 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Иван Денисов писал(а):
Задача: взять из реестра данные об окружении пользователя.
Думаю, следует различать "Взять из реестра" и "Взять из окружения". Переменные среды могут меняться в пределах одной сессии не меняя значения реестра.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 10:10 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2757
Valery Solovey писал(а):
Иван Денисов писал(а):
Задача: взять из реестра данные об окружении пользователя.
Думаю, следует различать "Взять из реестра" и "Взять из окружения". Переменные среды могут меняться в пределах одной сессии не меняя значения реестра.

Учту на будущее. Опирался на название раздела «Volatile Environment» — «Переменное Окружение» поэтому и, подумал, что так будет корректно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 11:30 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Кстати, в этой ветке хранятся не все переменные окружения. Переменные, которые пользователь добавляет в своё окружение через "C:\Windows\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables", попадают в другое место. То есть, неудачный поиск по Вашему пути не гарантирует отсутствие переменной в окружении.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 12:06 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2757
Valery Solovey писал(а):
Кстати, в этой ветке хранятся не все переменные окружения. Переменные, которые пользователь добавляет в своё окружение через "C:\Windows\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables", попадают в другое место. То есть, неудачный поиск по Вашему пути не гарантирует отсутствие переменной в окружении.
Правильно ли понимаю, что вы хотите сказать, что лучше использовать GetUserName или GetEnvironmentVariable? Как рекомендовал Александр.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 13:44 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Если цель - работа с переменными среды, а не работа с реестром, то - да. Потому что для вступления в силу значений из реестра программу придётся перезапустить.

Причём, не просто перезапустить, а перезапустить "с нуля". Дело вот в чём: если мы запускаем программу из уже запущенной консоли или какой-нибудь другой программы, то переменные среды будут скопированы из этой программы. И сверки с реестром не происходит. При запуске "с нуля" (или "из корня" не знаю, как правильно сказать применительно к windows), то есть, с рабочего стола или через "Run", переменные копировать неоткуда, потому они берутся из реестра. Всё это на основе наблюдений, и в мсдн-е, наверно, написано более аргументированно, однако, наблюдения эти меня не подводят, поэтому я им доверяю.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 14:20 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Иван Денисов писал(а):
использовать 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.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 14:23 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Правда, инит желательно в конфиг запихнуть, а не по месту, как у меня.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2013 14:26 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Ну и тип строк поменять, если в проекте есть один универсальный тип строки.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2020, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB