IronPython как движок для макросов в .NET приложениях
Подозреваю, многие из вас задумывались — как можно в .NET приложение добавить поддержку макросов — чтобы можно было расширять возможности программы без ее перекомпиляции и предоставить сторонним разработчикам возможность легко и просто получить доступ к API вашего приложения? В статье рассмотрено, как в качестве основы для выполнения макросов использовать IronPython — реализацию языка Python на платформе .NET.
Динамическая компиляция — слишком громоздко и тащит за собой использование Reflection. Однако, этот метод не лишен преимуществ — написанный макрос компилируется единожды и в дальшейшем может использоватся многократно — в виде полноценной .NET сборки. Итак — финалист — метод номер три — использование существующих DLR языков. В качестве такого языка выбираем IronPython (примите это как факт :). Текущая версия IPy — 2.0, взять можно на codeplex.com/IronPython
Перейдем непосредствено к кодированию. Для начала, рассмотрим интерфейс тестового приложения «Notepad».
В меню «Сервис» и разместим пункт «Макросы». Для примера рассмотрим простейший вариант формирования списка макросов — в каталоге с программой создадим папку «Macroses» файлы из этой папки станут пунктами меню.
MacrosToolStripMenuItem — класс-наследник от ToolStripMenuItem отличающийся только свойством MacrosFileName
Для начала, создадим макрос, который просмотрит текст в textBox`е и найдет все e-mail адреса вида «
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
». В папке Macroses создаем файл SaveEmail.py, запускаем приложение — и смотрим, что в меню Макросы появился пункт SaveEmail.
Теперь собственно ключевой момент — выполнение IPy скрипта и доступ его к интерфейсу. Добавляем к проекту ссылку на сборку IronPython.dll. И создаем класс MacroRunner — выполняющий скрипт.
publicclass MacroRunner { publicstatic Form CurrentForm;
publicstring FileName { get; set; }
public MacroRunner() { }
publicvoid Execute() { // собственно среда выполнения Python-скрипта IronPython.Hosting.PythonEngine pyEngine = new IronPython.Hosting.PythonEngine(); // важный момент - к среде выполнения подключаем текушую выполняемую сборку, т.к. // в ней собственно и объявлена форма, к которой необходимо получит доступ pyEngine.LoadAssembly(System.Reflection.Assembly.GetExecutingAssembly());
Ключевой момент — подключение к выполняющей среде IPy текущей сборки — для доступа к форме. Когда сборка подключена, в IPy скрипте появится возможность использовать классы пространства имен Notepad. Так же, через LoadAssebmly можно добавить и другие необходимые сборки — типа System.Windows.Forms — чтобы работать с формами.
Класс готов, теперь модифицируем обработчик клика на пунктах подменю Макросы
Здесь следует отметить следующий момент — чтобы передать в IPy-скрипт форму, из которой собственно вызывается макрос — используется статическое поле CurrentForm. В скрипте форма будет доступна как Notepad.MacroRunner.CurrentForm. В идеале, скрипт, разумеется, не должен иметь полного доступа к интерфейсу формы — а должен пользоватся только предоставленным API — и ограничиваться только им. Но сейчас этим заморачиваться не будем — и просто сделаем textBox открытым (Modifier = Public). Ну и кроме текстового поля, разрешим скрипту доступ к пункту меню Сервис (Modifier = Public).
Работа с формой закончена, собираем проект и открываем файл SaveEmail.py — теперь работаем только с макросами.
Т.к. сборка подключена к среде выполнения — то доступно пространство имен Notepad — в котором объявлены классы приложения. Как раз сейчас потребуется статический метод класса MacroRunner — чтобы получить доступ к активной форме (еще раз оговорюсь — что правильнее было бы предоставить не прямой доступ, а через класс-посредник — которые ограничит доступ определенным API). Ну а дальше все просто — получаем текст, регулярным выражением вытаскиваем email — и сохраняем их в файл в текущем каталоге.
Можно запустить приложение, ввести произвольный текст, содежащий email — и убедиться, что после того, как макрос отработал — в папке с выполняемой программой появился файл emails.txt.
Теперь еще один пример, что может сделать макрос — чуть интереснее предыдущего. Итак, создаем в папке Macroses файл UIModifier.py. Как можно догадаться по названию — макрос будет изменять элементы интерфейса приложения. Конкретно — добавит новый пункт в меню Сервис. Для того, чтобы можно было работать с элементами управления WinForms необходимо в среде выполнения IPy подключить сборку System.Windows.Forms. Это можно сделать в момент запуска скрипта из приложения — добавить еще один вызов LoadAssembly. Но мы решили — никаких перекомпиляций, пусть IronPython обходится своими силами. Ну что ж, силы есть :). Чтобы подключить сборку используется метод AddReference класса clr.
from Notepad import * main = MacroRunner.CurrentForm
import clr clr.AddReference("System.Windows.Forms") from System.Windows.Forms import *
def pyHello(s,e): MessageBox.Show("Hello from IPy!")
.NET Framework,
Плавающая точка в .NET - часть 1: принципы и форматы Данная статья представит основные принципы арифметических операций с плавающей точкой: числовые форматы, точности и достоверность, погрешности округления. Также в статью включено обсуждение типов плавающей запятой в .NET....
.NET Framework,
JIT-оптимизации Компилятор .NET Just-In-Time Compiler (JIT) считается многими одним из основных преимуществ производительности CLR по сравнению с JVM и другими управляемыми средами, которые используют двоичный код, скомпилированный компилятором JIT. ...
.NET Framework,
Инъекции CLR: замена методов во время выполнения Многие из нас, наверняка, были заинтересованы в том, как работает универсальный язык CLR. Одной из наиболее интересных вещей является динамический компилятор JIT (Just In Time Compiler). Мы рассмотрим то, как JIT компилирует MSIL и создадим утилиту, которая позволяет программным образом заменить любой метод (JIT) другим во время выполнения. Мы также создадим отладочную утилиту, которая прехватывает JIT-вызовы и выводит в консоль информацию о диагноcnbrt....
.NET Framework,
Оптимизация запуска приложений .NET Ждать, пока приложение запустится, неприятно для многих пользователей, поэтому ускорение запуска приложений клиентов может значительно улучшить первое впечатление от вашей работы. И так как скорость запуска имеет значение, следует знать факторы, которые на нее влияют, чтобы избежать распространенных ошибок....
.NET Framework,
Создание компилятора языка для .NET Framework Эксперты по компиляторам являются знаменитостями в компьютерном мире. Я видел, как Андерс Хейльсберг (Anders Hejlsberg) представлял презентацию на конференции разработчиков Professional Developers Conference и когда он сошел со сцены, его встретила целая орда мужчин и женщин, просящих поставить автограф на книгу, или сняться на фотографии вместе с ними. Люди, посвящающие свое время изучению и пониманию всех тонкостей лямбда-выражений, систем типов и языков сборки, кажутся своего рода носителями ...
.NET Framework,
Маршалинг данных между управляемым и неуправляемым кодом Посмотрим правде в глаза: нет в мире совершенства. Мало кто при разработке использует только управляемый код. А между тем, тяжким грузом лежат устаревшие неуправляемые приложения, с которыми приходится мириться. Есть ли способ интегрировать проекты, в которых задействован как управляемый, так и неуправляемый код? Какой вид принимает этот способ: вызов неуправляемого кода из управляемого приложения или вызов управляемого кода из неуправляемого приложения?...
.NET Framework,
Xml сериализация в .Net Framework 2.0 Xml широко используется в .Net приложениях, и .Net framework предоставляет богатые возможности по работе с Xml. Среди них: поддержка Xml DOM (System.Xml.XmlDocument), последовательное чтение - запись Xml, поддержка xPath и xQuery, поддержка XSLT, богатые возможности DataSet по работе с Xml и, наконец, Xml сериализация. ...