Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Операционные системы > Софт
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.05.2015, 13:38   #21
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию VB Script

Такс... Продолжаю.
Есть еще такая вот штука как выполнение скриптов. Помню тут на форуме была тема о том как взаимодействовать с другой системой на каком уровне. Многие говорили что вот мол не надо мешать языки, это пагубно и все такое. Не вижу в этом вообще ничего такого отвратного. Гибридная программа наоборот как показывает моя практика дает хорошие плоды, если ОС поддерживает конечно. Поэтому я вообще без зазрения совести прикрутил к ЯВУ работу на VBS. Команды и код передаются в виде текста (строки), описанной свободно в ковычках прямо в тексте программы. Причем Алиса настроена изначально таким образом, что перенос строки не прерывает описанную команду. Вот знаю что в Питоне и PHP тоже есть операторы типа ''' (уже не помню как точно), которые указывают что ниже текст мультистроковый. Очень удобная штука, лично я терпеть не люблю когда компиляторы Си или Паскаля говорят мол строка не закрыта.
Вот. Наверное поэтому у многих программистов сложился такой стереотип неделимости строки и невозможности описать многострочный текст в коде, а соответственно невозможности описать программу на другом языке в ЯВУ. Ну нет. Это из области мифов. Можно. И нужно.

Итак, класс:
Код:
(vbs := vscript)
Параметров у него нет.

Тело скрипта ассигнируется методом addcode.
В виде строки в него передается скрипт.:
Код:
(writeln (call vbs.addcode '
    Sub Farewell()
      MsgBox "Goodbye"
    End Sub
    
    Function hello()
      hello = "hi"
    End Function
    
') (call vbs.error))
Как видите строка открывается на одной линии и закрывается на другой, а внутри прямо так открытым кодом аз есьм иже херувимы самого скрипта.
Если в скрипте обнаружена ошибка vbs.error вернет ее текст, иначе пустую строку. Т.е. синтаксические ошибки можно обработать.

Далее остается только вызвать функции:
Код:
... := (call vbs.run 'hello')
В метод run передается имя функции. Соответственно результат возвращается. Если вызывается процедура, результат соответственно будет True если не будет ошибки или False в другом случае.

Как вариант еще можно просто вызвать расчет выражения.
Код:
(write (vbs '2+2'))
Соответственно заставит VBScript посчитать выражение и вернуть результат. Короче эвалюатор такой себе.

Опять таки эта фичка позволила мне решить достаточно много задач, которые были уже оформлены на VBS, но не собраны в единый проект. Разбежались программисты их создававшие или спились.
Так что я их поконсолидировал в код Алисы и отдал юзерам. Говорят что работает как надо.

В общем тут срабатывает тот же принцип что и в выше описанных FoxPro и ADO. Код передается в качестве открытого текста, и скармливается ядру или провайдеру. И те, кто критикуют такие гибридные ПО, уверен на 100% сами никогда от шаблонных традиций не отходили просто потому что кишка тонка. А зря. Прогресс этого не любит.

Где это у меня применяется? Есть некий сервер FTP, который расставлен клиентам (его пример я кстати тоже выкладывал на форум). Так вот Алиса прикручена и к нему, с такой целью, чтоб удаленно выполнять мои комманды и программы. Что-то вроде телнета.
Например есть такой код:
Код:
sub main()

        Set objWMIService = GetObject("winmgmts:\\127.0.0.1").InstancesOf("Win32_OperatingSystem")
        For Each x In objWMIService
            x.Description = "Бухгалтер Алла. Инв.№ 1950668"
            x.Put_
        Next

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\127.0.0.1\root\cimv2")
Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

For Each objComputer in colComputers
 err = objComputer.Rename("buhg_1_alla")
next

end sub
Это код выдранный из тырнета, который переименовывает комп и дает ему описание.
Сей (а точнее подобный) код я передаю серверу с командой "выполнить". Алиса его добавляет в объект vscript, выполняет и возвращает результат. И все. Задача решена.

И так же выполняю удаленно и другие скриптовые коды для, скажем, бэкапирования баз и файлов. Чистки мусора. Формирования документов на удаленных хостах... Да много чего. Удаленное управление требует подчас таких выкрутасов, которые можно решить только написав программу и выполнив ее. А чтоб не тормошить и прерывать работу юзеров я делаю это в фоне вот такими вот сплойтами, что ли...
Оч. часто, если скрипт однотипный для все хостов, просто рассылаю код всем дабы выполнение началось одновременно везде, чтоб я не ждал пока тот или инной хост обработается по очереди. Это экономит время, а программа делает за меня те или инные действия, как будто я залез по удаленке и сам в консоли начал исполнять комманды.
Экономлю себе же время короче говоря.

То же самое с Фокспро. На удаленках есть некие справочники, которые нужно обновлять или чистить. Посылаю в виде скрипта код на фоксе, который интерпретатор исполняет.
Данные таким образом держу актуальными всегда.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 13:58   #22
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А что за проблемы могут быть с реализацией работы с БД?
Это не работа с БД, а разработка БД -- своей, объектно-ориентированной. Код на Канторе всегда является описанием некого ОО-пространства. Это расширенный аналог AST, нужный для реализации ОО-системы, а для реализации обязательно нужна обратимость кода.
Vapaamies на форуме Ответить с цитированием
Старый 02.05.2015, 13:59   #23
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию WMI. Администрирование хоста

WMI использую уже давно, в рамки интерпретатора тоже влепил в числе первых компонентов.
Собственно сам алгоритм описан тут:
http://www.programmersclub.ru/wmi-w%...0%B9-%D1%87-1/
http://www.programmersclub.ru/wmi-w%...D1%82%D1%8C-2/

Все это упаковал в интерпретатор, чтоб было поудобнее.

Класс:
Код:
(w := wmi)
Он не особо разнообразен. Собственно основная работа лежит на выполнении запроса и прохода по нему.

Делается это примерно так:
Код:
(if (call w.open sql='select Caption,Default,PortName from Win32_Printer')
 (call w.scan
  (writeln w[Capacity])
 )
 (write (call w.error))
)
Я вот так вот сходу скриптик кинул, а теперь поясняю:
В метод Open параметром sql передается сам WQL запрос. Результат открытия False или True, чтоб проверить на ошибки при открытии.

Если запрос открыт, метод scan инициирует проход по полученной плоской табличке с запрошенными данными, при этом итератор переменной этого класса получает в виде массива значения каждой проходимой строки. Т.е. достаточно вызвать <переменка>[Имя поля] чтоб получить значение из набора из этого поля из текущей на итерации записи.

Собственно это единственное, что я использую из этого класса, т.е. являюсь наблюдателем за параметрами системы. Мало ли нужно узнать характеристики компа. С классом wmi это не проблема. И в реестре рыться не надо лишний раз.
Список принетров, процессов, драйверов, параметры процесора...
Короче говоря: https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
Минус пожалуй в том что далеко не все возможности WMI могу использовать, но такого требования не было. Имеется ввиду не все классы в запросе.
Однако для ревизий системы этого хватает.

Теоретически помимо запросов есть еще "возможность" редактирования параметров классов.
Описывается она так:
Код:
(call w.edit class='Win32_OperatingSystem' Description='"Моя любимя компушка"')
В параметр class передается имя класса, и далее остальные параметры=значения собственно говорят что в классе обновлять и на какие значения.
Да. Надо оговориться, что увы этот метод редактирования не оправдал надежды. Редактировать то редактирует, но никакого влияния на операционку это не оказывает. Как будто редактирование происходит в профиле пользователя, а не в контейнере системы. Увы, не смог я разобраться почему так происходит.
Если кому интересно есть обсуждение на форуме по этому поводу: http://www.programmersforum.ru/showthread.php?t=274202

Так что редактирование произвожу через VBScript.

На сим по WMI все.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 14:00   #24
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
а разработка БД -- своей, объектно-ориентированной.
А-а-а. Вон чего. БД типа Cashe как я понял? Иерархическая?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 14:14   #25
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию Реестр. INI файлы

Работа с реестром тоже имеется.
Класс:
Код:
(r := registry root='HKEY_LOCAL_MACHINE')
root определяет категорию реестра.

Для открытия ветки реестра есть метод Open
Код:
(call r.open '\Console' readonly create)
readonly и create опциональны. Первый указывает что открытие будет только для чтения, второй создает ветку если ее еще нет.
Результат True или False для проверок в IF
Как обычно метод error возвращает текст ошибки.

Проход по элементам открытой ветки - все тот же scan
Код:
	(call r.scan
	 (writeln r ' ' r[type] ' ' r[size] ' ' r[value])
	)
Итератор получает имя элемента в ветке, а массив итератора соответственно тип элемента, размер, и само значение.
Метод сканирования может получить селектор в виде имени секции, которая указывает в какой подветке из открытой ветки сделать проход:
Код:
(call r.scan section='autoexec' (writeln r ' - ' r[value]))
В данном примере проход будет делаться не по открытой ветке, а по ее подветке autoexec. Сделано просто для удобства, не более. Опционально. Не обязательно.

Запись в реестр осуществляется методом write
Код:
(writeln (call r.write key='\autoexec\int' value=123) (call r.error))
параметр key - полный путь к элементу реестра, а value - новое значение.
Если такого элемента нет - он создастся. Ошибку записи можно будет обработать, получив текст методом error, если write вернет False.

Если классу указать ИНИ файл, то работать он будет с ним а не с реестром:
Код:
(r := registry ini='d:\файл.INI')
В этом случае можно получить данные обращением к массиву переменной следующим образом:
Код:
(write r[Секция,Значение])
Т.е. указав секцию и элемент через запятую
I'm learning to live...

Последний раз редактировалось Stilet; 02.05.2015 в 14:16.
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 14:22   #26
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию Регулярные выражения.

Для регулярок есть свой класс:
Код:
(reg := regexp)
В нем всего два метода.

Первый это проверка на совпадение:
Код:
(call reg.match pattern='[А-яЁё\s]+' value='ОЭС Урала')
Параметр Pattern принимает значение маски, а Value источник сравнения.
True - если выражение подходит, False в противном случае.
Используется опять таки в IF или циклах.

Второй это замена:
Код:
(write (call reg.replace pattern='[А-яЁё\s]+' value='ОЭС Урала' expression='123'))
Яйца те же, только добавляется параметр expression, указывающий на что именно заменять. Результат возвращается в виде модифицированной посредством замены строки.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 14:34   #27
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Тогда уж ((K)) - символ языка Кантор.
Это не единственный синтаксис в Канторе, в нем будет несколько альтернативных возможностей записать одно и то же.

Раз уж так вышло, что для ОО-основы в обязательном порядке нужна обратимость кода, я решил оттянуться по полной и не ограничиваться одним синтаксисом. В Канторе (тогда еще Оно) с первого дня их разрабатывалось как минимум два, плюс еще кириллица в уме.

Символ Кантора -- стилизованная фрактальная снежинка-шестеренка:

Цитата:
Сообщение от Stilet Посмотреть сообщение
БД типа Cashe как я понял? Иерархическая?
Не знаком с Cache, и классификация "иерархическая" меня напрягает. Это же древний какой-то подход к БД, дореляционный? В Канторе из-за множественного наследования линия наследования -- граф. Он тоже считается за иерархию?
Vapaamies на форуме Ответить с цитированием
Старый 02.05.2015, 15:38   #28
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
я решил оттянуться по полной и не ограничиваться одним синтаксисом.
Ну и правильно. Без творческого подхода инструмент получится неперспективным.
Цитата:
Не знаком с Cache, и классификация "иерархическая" меня напрягает. Это же древний какой-то подход к БД, дореляционный?
Ну не. Это современные средства, и усиленно продвигаемые. И тут уж не особо важно граф или лорд, как в том анекдоте. Кэш это СУБД, где единица информации - класс. А запись - объект класса. Lotus посложнее, но тоже примерно в таком же ключе. Вот и получается что Кантор твой тоже иерархический, раз одно связано с другим по некоему признаку во множественной связке. Пусть даже дело только в наследовании, это не важно. И это далеко не загибающаяся технология, тут я с тобой не согласен.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 16:56   #29
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию Stream. Поток данных.

Класс для работы с потоком:
Код:
(sm := stream type='memory')
Type опциональный параметр. Может принимать три значения:
  1. memory - Поток байт. TMemoryStream
  2. file - файловый поток. TFileStream
  3. string - Строковый поток. TStringStream
Если указан тип file то добавляется параметр from, с именем файла
Код:
(sm := stream type='file' from='d:\файлик')
Если type не указан по умолчанию создается поток memory

для открытия файла так же может применяться отдельно метод open. Собственно делает то же самое что и указание file в качестве типа.
Особо его не использую.

Для сохранения потока в файл использую метод save:
Код:
(call sm.save file='d:\1\q')
Если тип file значит поток закрывается и освобождается до следующего открытия. Иначе поток просто копируется в файл.

Переход по потоку производит метод Pos:
Код:
(call sm.pos 5)
По факту становится на пятый байт. Нумерация тут с единицы.

Считывание может производится несколькими способами. Поток считается массивом, поэтому считку можно производить как с обычного массива. При этом есть возможность указать тип считываемого и перекодировку в систему счисления.
Пример:
Код:
(write 
 sm[] ' Считывает с текущей позиции байт' 
 sm[5.byte.16] ' Считывает с пятой позиции байт, конвертируя с 16-ричную СС' 
 sm[.word.5] ' Считывает с текущей (раз не указано) позиции слово. Конвертация в 5-чную СС' 
 sm[.word] ' Считывает с текущей позиции слово.'
)
Как вариант можно использовать метод считывания read.
Код:
(call sm.read pos=23 len=50 <тип считываемого>)
Pos это номер байта для считывания
len - длина считываемого блока.
Тип считываемого следующий:
  • string - Len указывает сколько символов воспринять как строку
  • integer - Len игнорируется, считывается тип целого
  • byte - Len игнорируется, считывается байт
  • bytes - Len указывает сколько байт считать в массив (еще не дописано)
  • word - Len игнорируется, считывается слово
  • cardinal - Len игнорируется, считывается двойное слово
После считывания курсор указывает на позицию, следующую за считанным, как и положено

Запись:
Код:
(call sm.write str='строка')
Код:
(call sm.write byte=12 )
Код:
(call sm.write word=34 )
Код:
(call sm.write dword=223343 )
Код:
(call sm.write qword=374625737824)
Соответственно записывается элемент определенного типа.
Надо будет сделать так, чтоб можно было в одной функции несколько параметров обрабатывать (запомню в ремарке)

Ну или по простому:
Код:
(call s.write 'Строку' 12 2.365 44 'опять строку')
Т.е. список разнотипного, и пусть интерпретатор сам определяет как записывать согласно типу данных.

Тыкс... Проход по потоку. Scan. Живой пример кстати:
Код:
 (call sm.scan
  (c := sm)
  (c := (213 * (c div 213) + c - ebp6))

  (res += (chr c))
  
  (c := sm)
  (c := (c div 71))
  (ebp6 := (c + ebp6 + (ebp6 + (i ++))))
 )
Хеширует у меня какой-то пароль, если память не изменяет.
res = результирующая строка с хешем.
i - просто счетчик.
Переменная класса получает статус итератора, и возвращает байт.
Может быть как-нибудь потом допилю селекцию что в итератор при проходе выбирать, байт, слово, строку... Пока не делал.
Вездесущий Scan практически везде где есть необходимость прохода полностью заменяет цикл. Практически стал стандартом языка уже.
Нда...

Очистка потока:
Код:
(call sm.clear)
Поток получает нулевой размер.

Метод error тоже присутствует, и возвращает сообщения при ошибках. Тоже такой вездесущий получился.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 17:27   #30
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию Visual Alisa. GUI.

Скромная такая попытка сделать интерфейс пользователя. Так то сам интерпретатор по умолчанию - консоль. Ну вот и решил разнообразить себе "зызнь". В общем запилил основы для визуальных компонент. Интерпретатор для такого кода нужно запускать с параметром gui в командной строке.
Вот знаю что в Питоне тоже есть такая возможность - графически накидать на форму чего-то. Ну и правильно сделали. PHP вроде как курит в сторонке, хотя может и есть какая нить Visual PHP. Вон Эмбаркадеро вроде пыталось такое разработать, чем кончилось не помню, но не похоже чтоб разработка покорила сердца масс.

Да...

По умолчанию его консоль является главной формой, и для нее есть класс mainform, собственно этой формой управляющий. Консоль чтоб не мешала можно отключить, тогда получим голую форму. Компонентов на данный момент, которыми можно оперировать мало, но главное что есть база для увеличения их численности. Сразу покажу код чтоб пояснять по нему как все это выглядит
Код:
(MyForm := mainform nolog w=200 h=200 y=0 align=hcenter caption='Forms'
  tree=(MyTree align=client 
   onclick=(writeln (call MyForm.MyTree.path))
  )
  button=(MyButton align=top caption='12345' --glyph='d:\1\eye.jpg'
   onclick=(alert 'Кликнута MyButton')
  )
  image=(MyImage file='d:\1\eye.jpg' align=client stretch=yes)
  grid=(MyGrid cols=5 rows=5 align=client)
  
  toolbar=(MyToolBar buttonwidth=32 buttonheight=32
   button=(b1 -caption='qwe' image='d:\_projects\Delphi_projects\Ico\ASUKs.ICO'
    onclick=(alert 'Кликнута первая кнопка')
   ) 
   button=(b2 -caption='rrr' image='d:\_projects\Delphi_projects\Ico\ASUExit.ICO'
    onclick=(alert 'Кликнута вторая кнопка')
   )
   separator=()
   button=(b3 -caption='rrr' image='d:\_projects\Delphi_projects\Ico\EVIew9History.ICO'
    onclick=(alert 'Кликнута третья кнопка')
   )
  )
  
)

Показывает форму на экране
(call MyForm.show)

Добавляет элемент к дереву
(call MyForm.MyTree.add 'uno\duo\tres' 'uno\duo\quadro' 'uno\5\kk')

Удаляет элемент
(call MyForm.MyTree.del 'uno\duo\tres')

Устанавливает кол-во строк и колонок. Если цифры не указаны - возвращает значение количества соответственно
(write (call MyForm.MyGrid.cols 5) (call MyForm.MyGrid.rows 5))

Устанавливает значение ячейки в гриде. Если text не указан - считывает значение из ячейки
Координаты которой X и Y
(write (call MyForm.MyGrid.cell x=1 y=2 text='Текст') (call MyForm.error))
Теперь по порядку. Форма и ее компоннеты описываются как класс. Все инкапсулировано, даже обработчики.
Для формы можно установить координаты (параметры x и y), размер (h и w как высота и ширина), выравнивание (align), наподобие делфийского, заголовок (caption).
Флаг "nolog" убирает консоль из формы.

внутрь формы помещаются компоненты, описываемые параметрами. Имя параметра представляет собой класс компонента, а значение уже характеризует сам компонент.
Так в примере
Код:
  tree=(MyTree align=client 
   onclick=(writeln (call MyForm.MyTree.path))
  )
Означает следующее: Первым в списке параметров идет имя компонента - MyTree. Далее разнообразные параметры и обработчики событий. У каждого компонента есть свои свойства. В качестве примера у компонента Дерева есть свойство path, к которому обращаясь по полному пути MyForm.MyTree.path можно получить путь к текущему элементу. Характерна эта запись как раз для события onclick. Понятное дело что и в других событиях можно использовать.

Я особо не буду вдаваться в описания, думаю что в примере слова, подобранные в качестве имен свойств достаточно рассказывают для чего они нужны.
Функция alert - обычный MessageBox.

GUIшка, повторюсь, не дописана до полного, так сказать, хаоса. поэтому применения ей пока серьезного нет. Но в планах. Даже есть идеи - написать IDE для Алисы на ней же. Ну будет время, посмотрим. Не думаю что будет много препятствий.


По поводу работы с формой и ее компонентами тоже пожалуй не стану много писать. Думаю в примере наглядно видно, в каком направлении я вижу эту разработку.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хочу написать программу для себя Marishka.S Помощь студентам 7 02.10.2011 17:23