.NETアプリケーションのマクロエンジンとしてのIronPython

多くの人が.NETアプリケーションにマクロサポートを追加するにはどうすればよいか考えていると思うので、再コンパイルせずにプログラムの機能を拡張し、サードパーティの開発者にアプリケーションのAPIに簡単かつ簡単にアクセスする機会を提供できますか? この記事では、.NETプラットフォームのPython実装であるIronPythonをマクロ実行の基礎として使用する方法について説明します。



まず、それを決定する必要があります-「マクロ」という言葉の意味-これは、プロジェクトを再コンパイルしなくても特定のAPIにアクセスできるスクリプトです。 つまり フォームから値を取得し、それらを変更します。これらはすべて、アプリケーションを変更せずに、ランタイムモードで実行します。



最初に思い浮かぶオプションは、単純なスクリプト言語用の独自のインタープリターを作成することです。 2つ目は、(同じC#の).NET言語の動的コンパイル-アセンブリの動的な読み込みとReflectionによる実行です。 3番目は、インタープリター.NET言語(DLR)の使用-IronPythonまたはIronRubyです。



独自の言語と.NET相互運用機能を備えたインタープリターを作成するのは簡単な作業ではなく、愛好家に任せましょう。

動的コンパイル-面倒すぎて、Reflectionの使用を引きずります。 ただし、この方法には利点があります-作成されたマクロは一度コンパイルされ、将来的には繰り返し使用できるようになります-完全な.NETアセンブリの形で。 したがって-ファイナリスト-方法3-既存のDLR言語を使用します。 そのような言語としてIronPythonを選択します(これを事実として受け入れます:)。 IPyの現在のバージョンは2.0で、 codeplex.com / IronPythonで入手できます



コーディングに直接進みます。

開始するには、テストアプリケーション「メモ帳」のインターフェースを検討してください。



ImageShack.usがホストする画像





メニューの「サービス」で、アイテム「マクロ」を配置します。 たとえば、マクロのリストを作成する最も簡単なオプションを検討してください。プログラムディレクトリで「Macroses」フォルダーを作成すると、このフォルダーのファイルがメニュー項目になります。



private void Main_Load( object sender, EventArgs e)

{

MacrosToolStripMenuItem itm = null ;

string [] files = Directory .GetFiles( @".\Macroses" );

foreach ( string file in files)

{

itm = new MacrosToolStripMenuItem(Path.GetFileNameWithoutExtension(file)) { MacrosFileName = file };

itm.Click += new EventHandler(macroToolStripMenuItem_Click);

ToolStripMenuItem.DropDownItems.Add(itm);

}

}



internal class MacrosToolStripMenuItem : ToolStripMenuItem

{

public MacrosToolStripMenuItem( string FileName) : base (FileName) { }

public string MacrosFileName { get ; set ; }

}





* This source code was highlighted with Source Code Highlighter .








MacrosToolStripMenuItem-MacrosFileNameプロパティのみが異なるToolStripMenuItemからの継承クラス



最初に、textBoxのテキストを調べて、「vpupkin@mail.ru」という形式のすべての電子メールアドレスを見つけるマクロを作成します。 MacrosesフォルダーでSaveEmail.pyファイルを作成し、アプリケーションを起動します-SaveEmailアイテムがMacrosメニューに表示されることを確認します。



ここで重要なのは、IPyスクリプトの実行とインターフェイスへのアクセスです。 IronPython.dllアセンブリへのリンクをプロジェクトに追加します。 そして、実行スクリプトであるMacroRunnerクラスを作成します。



public class MacroRunner

{

public static Form CurrentForm;



public string FileName { get ; set ; }



public MacroRunner() { }



public void Execute()

{

// Python-

IronPython.Hosting.PythonEngine pyEngine = new IronPython.Hosting.PythonEngine();

// - , ..

// ,

pyEngine.LoadAssembly(System.Reflection. Assembly .GetExecutingAssembly());



try

{

pyEngine.ExecuteFile(FileName);

}

catch (Exception exc)

{

MessageBox.Show(exc.Message);

}

}

}





* This source code was highlighted with Source Code Highlighter .








キーポイントは、現在のアセンブリIPy環境に接続することです-フォームにアクセスします。 アセンブリが接続されると、IPyスクリプトでメモ帳の名前空間クラスを使用できます。 また、LoadAssebmlyを使用して、System.Windows.Formsなどの他の必要なアセンブリを追加して、フォームを操作できます。

クラスの準備ができました。マクロサブメニュー項目のクリックハンドラーを変更します。



protected void macroToolStripMenuItem_Click( object sender, EventArgs e)

{

MacrosToolStripMenuItem item = sender as MacrosToolStripMenuItem;



MacroRunner runner = new MacroRunner() { FileName = item.MacrosFileName };

MacroRunner.CurrentForm = this ;

runner.Execute();

}




* This source code was highlighted with Source Code Highlighter .








ここで、マクロが実際に呼び出されるフォームをIPyスクリプトに転送するために、静的フィールドCurrentFormが使用されることに注意してください。 スクリプトでは、フォームはNotepad.MacroRunner.CurrentFormとして使用できます。 理想的には、もちろん、スクリプトはフォームインターフェイスへの完全なアクセス権を持たず、提供されたAPIのみを使用し、それに限定されるべきです。 しかし、今はこれに煩わされることはなく、単にtextBoxを開きます(修飾子=パブリック)。 さて、テキストフィールドに加えて、スクリプトがメニュー項目ツール(修飾子=パブリック)にアクセスできるようにします。



フォームの操作が完了したら、プロジェクトを収集してSaveEmail.pyファイルを開きます-現在はマクロのみを使用しています。



したがって、最初のマクロはSaveEmail.pyです。



from Notepad import *

import re



text = MacroRunner.CurrentForm.textBox.Text

links = re.findall( "\w*@\w*\.\w{2,4}" , text)

file = open( "emails.txt" , "w" )

file.write( "\n" .join(links))

file.close()




* This source code was highlighted with Source Code Highlighter .








なぜなら アセンブリはランタイムに接続されます— Notepad名前空間が利用可能です—アプリケーションクラスが宣言されます。 ちょうど今、MacroRunnerクラスの静的メソッドが必要です-アクティブフォームにアクセスするには(再び、直接アクセスではなく、中間クラスを介して提供する方が正しいでしょう-特定のAPIへのアクセスを制限します)。 それでは、すべてが簡単です。テキストを取得し、正規表現を使用して電子メールを引き出し、現在のディレクトリのファイルに保存します。



アプリケーションを起動し、電子メールを含むテキストを入力します。マクロが機能した後、emails.txtファイルが実行中のプログラムのあるフォルダーに表示されることを確認します。



マクロができることのもう1つの例は、前のものよりも少し興味深いものです。 そのため、MacrosesフォルダーにUIModifier.pyファイルを作成します。 名前から推測できるように、マクロはアプリケーションインターフェイスの要素を変更します。 具体的には、[ツール]メニューに新しいアイテムを追加します。 WinFormsコントロールを使用するには、System.Windows.FormsアセンブリをIPyランタイムに接続する必要があります。 これは、スクリプトがアプリケーションから実行されたときに行うことができます-LoadAssemblyに別の呼び出しを追加します。 しかし、私たちは決心しました-再コンパイルはせず、IronPythonにそれだけをさせてください。 まあ、強さがあります:)。 アセンブリを接続するには、clrクラスのAddReferenceメソッドを使用します。



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!" )



item = ToolStripMenuItem()

item.Name = "pybtn"

item.Text = "Python created!"

item.Click += pyHello



main.ToolStripMenuItem.DropDownItems.Add(item)





* This source code was highlighted with Source Code Highlighter .








すべてが単純です-現在のフォームを取得し、System.Windows.Formsアセンブリを接続し、System.Windows.Forms名前空間からすべてをインポートします-これは便利です。

pyHello-シンプルなイベントハンドラ-作成されたメニュー項目をクリックすると、メッセージが表示されます。



アプリケーションを起動し、マクロを実行します。 メニュー項目サービスを見ます:



ImageShack.usがホストする画像





メニュー項目「Python Created!」をクリックすると、標準のMessageBoxが表示されます。実際には、それらが目指していたものです。



ご清聴ありがとうございました:)






All Articles