Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Windows Scripting с использованием JScript. Доступ к реестру.  (Прочитано 25912 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« : 22-04-2010 10:39 » 

Написал сперва скрипт на VBScript (расширение vbs), но по органическому неперевариванию VB решил переписать его на JS (расширение wsf). И заткнулся на работе с реестром...

Для VBS примеры работы с реестром нашел тут:
http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/registry/#EnumSubkeys.htm

В MSDN:
http://msdn.microsoft.com/en-us/library/aa390387%28v=VS.85%29.aspx

В реестре мне нужно перебирать ветки реестра (EnumKey). На VBS это выглядит так:

Код:
Dim oraReg, oraKeyPrefix, oReg

const HKEY_LOCAL_MACHINE = &H80000002
oraReg = "SOFTWARE\ORACLE"
raKeyPrefix = "KEY_OraClient10g_home"
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
 
Function getOraHome
  Dim subkey, arrSubKeys

  call oReg.EnumKey(HKEY_LOCAL_MACHINE, oraReg, arrSubKeys)

  For Each subkey In arrSubKeys
    If InStr(subKey, oraKeyPrefix) Then
      call oReg.GetStringValue(HKEY_LOCAL_MACHINE, oraReg & "\" & subKey, "ORACLE_HOME", getOraHome)
    End Iif
  Next
End Sub

На JS получилось вот такое:

Код:
var HKEY_LOCAL_MACHINE = 0x80000002;
var reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default:StdRegProv");
var oraReg = "SOFTWARE\\ORACLE";
var oraKeyPrefix = "KEY_OraClient10g_home";

function getOraHome()
{
  var keys, key;

  reg.EnumKey(HKEY_LOCAL_MACHINE, oraReg, keys);
  
  for (key in keys)
  {
    if (key.indexOf(oraKeyPrefix) == 0)
    {
      reg.GetStringValue(HKEY_LOCAL_MACHINE, oraReg + "\\" + key, "ORACLE_HOME", key);
      return key;
    }
  }

  return null;
}

В случае VBS работает, а в JS EnumKey всегда возвращает в keys null (или ничего не присваивает). Проверил - объект "StdRegProv" создается - не null.
Может я не понимаю нюансов конвертации VBS API в JS...
« Последнее редактирование: 22-04-2010 10:43 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 22-04-2010 11:05 » 

Вот тут пример от MS

http://msdn.microsoft.com/en-us/library/Aa394616.aspx

В JScript нет встроенных out и in-out параметров. Их нужно получать как отдельные объекты и работать уже с ними.
« Последнее редактирование: 22-04-2010 11:08 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #2 : 22-04-2010 11:07 » 

Рабочий пример из моего кода. Функция возвращает значение ключа. Если не существует - создает с defval.
Код: (Text)
function regRead(key, defval)
{
    var s=defval;
    try
    {
        s=WSHShell.RegRead(key);
    }
    catch(err)
    {
        s=defval;
        WSHShell.RegWrite(key, defval, "REG_SZ");
    }
    return s;
}

AdminEmail=regRead("HKLM\\Software\\Sodat\\Server\\AdminEmail", "user@domain.ru")
 
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #3 : 22-04-2010 11:08 » 

Для Windows Scripting однозначно рекомендую сайт http://www.script-coding.info/index.html
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 22-04-2010 11:10 » 

baldr, можно и так.

Но там выше другая интересная проблема - работа с COM-объектами с помощью JScript и out-параметры в вызовах.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 22-04-2010 11:12 » 

Дим, это пипец же... Легче на С++ написать.

Причем, как видите, задачка элементарная: пытаюсь определить "домашнюю" директорию клиента Oracle 10g.
« Последнее редактирование: 22-04-2010 11:14 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #6 : 22-04-2010 11:15 » 

С out-параметрами в JScript, действительно, есть проблема. В VBScript с ними все гораздо проще.
Вот другой пример...
Код: (Text)
// Here we will search our registry log folder and find all registry log file entries
HKEY_LOCAL_MACHINE = 0x80000002;
var Locator = new ActiveXObject("WbemScripting.SWbemLocator");
var ServerConn = Locator.ConnectServer(null, "root\\default");
var Registry = ServerConn.Get("StdRegProv");
var Method = Registry.Methods_.Item("EnumKey");
var p_In = Method.InParameters.SpawnInstance_();
p_In.hDefKey=HKEY_LOCAL_MACHINE;
p_In.sSubKeyName = "Software\\Sodat";
var p_Out = Registry.ExecMethod_(Method.Name, p_In);
var keys=p_Out.sNames.toArray();
for (i=0; i<keys.length; i++)
{
    if (keys[i]=="Client" || keys[i]=="Server")
    {
        // Here do something
    }
}
 
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 22-04-2010 11:26 » 

Ужасно.

Давайте на минутку отвлечемся от темы: не знает ли кто, как узнать путь к клиенту Оракла без этих наворотов?
Первое, что приходит на ум - получить ключ через WScript.Shell -> RegRead:
http://msdn.microsoft.com/ru-ru/library/x05fawxd.aspx
Точнее тупо перебрать несколько вариантов путей и хоть один да сработает.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #8 : 22-04-2010 12:42 » 

Код: (Text)
var WSHShell = WScript.CreateObject("WScript.Shell");

// Here we will search our registry log folder and find all registry log file entries
HKEY_LOCAL_MACHINE = 0x80000002;
var Locator = new ActiveXObject("WbemScripting.SWbemLocator");
var ServerConn = Locator.ConnectServer(null, "root\\default");
var Registry = ServerConn.Get("StdRegProv");
var Method = Registry.Methods_.Item("EnumKey");
var p_In = Method.InParameters.SpawnInstance_();
p_In.hDefKey=HKEY_LOCAL_MACHINE;
p_In.sSubKeyName = "Software\\ORACLE";
var p_Out = Registry.ExecMethod_(Method.Name, p_In);
var keys=p_Out.sNames.toArray();

for (i=0; i<keys.length; i++)
{
    var Method = Registry.Methods_.Item("EnumValues");
    var p_In = Method.InParameters.SpawnInstance_();
    p_In.hDefKey=HKEY_LOCAL_MACHINE;
    p_In.sSubKeyName = "Software\\ORACLE\\"+keys[i];
    var p_Out = Registry.ExecMethod_(Method.Name, p_In);
    if (p_Out.sNames==null) continue;
    var newkeys=p_Out.sNames.toArray();
    for (j=0; j<newkeys.length; j++)
    {
        if (newkeys[j]=="ORACLE_HOME")
        {
            val=WSHShell.RegRead("HKLM\\Software\\ORACLE\\"+keys[i]+"\\ORACLE_HOME");
            WScript.Echo(val);
            WScript.Quit();
        }
    }
}

хехе Улыбаюсь
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 22-04-2010 15:31 » 

Я - сторонник в таких случаях делать обёртки на будущее Улыбаюсь

В отдельном файле - расширяемая библиотека на тему:
Код: (Javascript) registry.js
// Конструктор объекта метода COM-объекта WMI.
function WMIMethod(wmiObject, methodName) {

  // Атрибуты объекта.

  // Экземпляр метода.
  var _method;

  // Экземпляр коллекции входных параметров.
  var _inputParameters;

  // Экземпляр коллекции выходных параметров.
  var _outputParameters;

  // Методы объекта.

  // Коллекция выходных параметров.
  this.getOutputParameters = function() {
    return _outputParameters;
  }

  // Коллекция входных параметров.
  this.getInputParameters = function() {
    return _inputParameters;
  }

  // Установка значений входных параметров.
  this.setInputParameters = function(parameters) {
    for(key in parameters) {
      eval("_inputParameters." + key + " = parameters[key]");
    }
  }

  // Исполнение.
  this.execute = function() {
    _outputParameters = wmiObject.ExecMethod_(_method.Name, _inputParameters);
  }
 
  // Инициализация.

  _method = wmiObject.Methods_.Item(methodName);
  _inputParameters = _method.InParameters.SpawnInstance_();
  _outputParameters = null;
}

// Конструктор объекта для работы с реестром.

// Константы.

// Корень локальной машины.
Registry.prototype.HKLM = 0x80000002;

// Типы значений.
Registry.prototype.REG_SZ = 1;
Registry.prototype.REG_EXPAND_SZ = 2;
Registry.prototype.REG_BINARY = 3;
Registry.prototype.REG_DWORD = 4;
Registry.prototype.REG_MULTI_SZ = 7;

function Registry() {

  // Атрибуты объекта.

  // COM-объект - WMI провайдер реестра.
  var _registryProvider = null;

  // Методы объекта.

  // Возвращает непосредственные ключи указанной ветви дерева.
  this.getSubKeys = function(rootKey, keyPath) {
    var keys = new Array();
    var enumKeys = new WMIMethod(_registryProvider, "EnumKey");
    enumKeys.setInputParameters({ hDefKey: rootKey, sSubKeyName: keyPath });
    enumKeys.execute();
    with(enumKeys.getOutputParameters()) {
      if(sNames != null) {
        keys = sNames.toArray();
      }
    }
    return keys;
  }

  // Возвращает значения ключа указанной ветви дерева.
  this.getValues = function(rootKey, keyPath, valueName) {
    var result = new Array();
    var valuesNames, valuesTypes;
    var enumValues = new WMIMethod(_registryProvider, "EnumValues");
    enumValues.setInputParameters({ hDefKey: rootKey, sSubKeyName: keyPath });
    enumValues.execute();
    with(enumValues.getOutputParameters()) {
      if(sNames != null && Types != null) {
        valuesNames = sNames.toArray();
        valuesTypes = Types.toArray();
        for(var i = 0; i < valuesNames.length; ++i) {
          result.push({ name: valuesNames[i], type: valuesTypes[i] });
        }
      }
    }
    return result;
  }

  // Возвращает значение из ключа.
  this.read = function(rootKey, keyPath, valueName) {
    var values = this.getValues(rootKey, keyPath);
    var valueType = null;
    for(i in values) {
      if(values[i].name == valueName) {
        valueType = values[i].type;
        break;
      }
    }
    var getMethodName = "";
    switch(valueType) {
      case Registry.prototype.REG_SZ:
        getMethodName = "GetStringValue";
        break;
      case Registry.prototype.REG_EXPAND_SZ:
        getMethodName = "GetExpandedStringValue";
        break;
      case Registry.prototype.REG_BINARY:
        getMethodName = "GetBinaryValue";
        break;
      case Registry.prototype.REG_DWORD:
        getMethodName = "GetDWORDValue";
        break;
      case Registry.prototype.REG_MULTI_SZ:
        getMethodName = "GetMultiStringValue";
        break;
    }
    var get = new WMIMethod(_registryProvider, getMethodName);
    get.setInputParameters({ hDefKey: rootKey, sSubKeyName: keyPath, sValueName: valueName });
    get.execute();
    with(get.getOutputParameters()) {
      switch(valueType) {
        case Registry.prototype.REG_SZ:
        case Registry.prototype.REG_EXPAND_SZ:
          return sValue;
        case Registry.prototype.REG_BINARY:
          return uValue.toArray();
        case Registry.prototype.REG_DWORD:
          return uValue;
        case Registry.prototype.REG_MULTI_SZ:
          return sValue.toArray();
      }
    }
  }

  // Вспомогательные функции.

  function _createRegistryProvider() {
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
    var connection = locator.ConnectServer(null, "root\\default");
    return connection.Get("StdRegProv");
  }

  // Инициализация

  _registryProvider = _createRegistryProvider();

}

В другом файле - использование для решения конкретной задачи.
Код: (Text) regtest.wsf
<job id="RegistryTest">
  <script language="JScript" src="registry.js"/>
  <script language="JScript">
    var registry = new Registry();
    WScript.Echo(registry.read(Registry.prototype.HKLM, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "CommonFilesDir"));
    WScript.Echo();
    var subKeys = registry.getSubKeys(Registry.prototype.HKLM, "SOFTWARE\\Microsoft");
    for(i in subKeys) {
      WScript.Echo(subKeys[i]);
    }
  </script>
</job>

Соответственно, написанное baldr начинает выглядеть примерно как (не отлаживал):
Код: (Text) searchora.wsf
<job id="RegistryTest">
  <script language="JScript" src="registry.js"/>
  <script language="JScript">
    var registry = new Registry();
    var rootPath = "SOFTWARE\\Oracle";
    var subKeys = registry.getSubKeys(Registry.prototype.HKLM, rootPath);
    for(var i in subKeys) {
      var subKey = rootPath + "\\" + subKeys[i];
      var values = registry.getValues(Registry.prototype.HKLM, subKey);
      for(var j in values) {
        var searchName = "ORACLE_HOME";
        if(values[j].name == searchName) {
          WScript.Echo(registry.read(Registry.prototype.HKLM, subKey, searchName));
          WScript.Quit();
        }
      }
    }
  </script>
</job>

P.S. В коде нет проверок на ошибки - желающие добавят сами.
« Последнее редактирование: 23-04-2010 10:12 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 23-04-2010 03:30 » 

Вы, граждане, маньяки Улыбаюсь
Спасибо.
« Последнее редактирование: 23-04-2010 03:34 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #11 : 23-04-2010 05:47 » 

Ну, еще как вариант такой:
Вызываем
regedit /e orapath.reg "HKEY_LOCAL_MACHINE\Software\ORACLE"
А потом в файле orapath.reg ищем строку "ORACLE_HOME"
Улыбаюсь
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 23-04-2010 05:51 » 

лично мне кажется, что последний метод наиболее простой.
baldr, 5+
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 23-04-2010 06:03 » 

me* вычёркивает Лёху из списка маньяков
Записан

baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #14 : 23-04-2010 06:09 » 

Алексей1153++ - рано.. Идеологически все равно было бы правильнее писать на чистом JScript... Улыбаюсь
Еще вариант:
Код:
C:\>where tnsping
D:\oracle\product\10.2.0\client_1\BIN\TNSPING.EXE
То есть команда where вернет путь к файлу. Можно перенаправить вывод в файл и опять оттуда читать..
Минусы - работает только на [2K Resource Kit / Windows 2003]
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 23-04-2010 06:10 » 

me* заносит Лёху в список маньяков (ПСЖ)
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 23-04-2010 20:10 » 

baldr, гениально Улыбаюсь
Но подобный метод я уже использовал: парсил PATH на предмет пути к исполняемым файлам Оракл с последующим преобразованием строки. А потом захотелось чтобы красиво было...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #17 : 29-04-2010 12:59 » new

вот так можно работать с out-параметрами

Код:
var HKEY_LOCAL_MACHINE = 0x80000002;
var oraReg = 'SOFTWARE\\ORACLE';
var reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default:StdRegProv");
var objInParams = reg.Methods_("EnumKey").InParameters.SpawnInstance_();

objInParams.hDefKey = HKEY_LOCAL_MACHINE;
objInParams.sSubKeyName = oraReg;
var objOutParams = reg.ExecMethod_("EnumKey", objInParams);
var sNames = objOutParams.sNames.toArray();
for (var i=0; i<=sNames.length-1; i++) {
    WScript.Echo(sNames[i]);

    objInParams = reg.Methods_("GetStringValue").InParameters.SpawnInstance_();
    objInParams.hDefKey = HKEY_LOCAL_MACHINE;
    objInParams.sSubKeyName = oraReg + "\\" + sNames[i];
    objInParams.sValueName = 'ORACLE_HOME';
    objOutParams = reg.ExecMethod_("GetStringValue", objInParams);
    WScript.Echo(objOutParams.Value);
}


спрашивать как и что меня бесполезно, т.к взято отсюда
Записан

I Have Nine Lives You Have One Only
THINK!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines