ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

Visual Studio 2005 for IronPythonで作ったコードを ipy.exe 単体で動かせるようにするには?

折角作ったコードを、Visual Studio 2005を入れてない方にも試してもらいたいと思いまして、ちょっと調べてみました。


Visual Studio 2005 for IronPythonのウィザードは、Program.py と Form1.py の2ファイルを生成しますんで、以下のようにすれば、とりあえず ipy.exe(IronPython)単体で動かせるようです。


1.Form1.py + Program.pyのソースを合体させる。

2.Program.pyのメインルーチン呼び出し部分で、"Program"を"__main__"に変更する。

if __name__ == "Program":
    IpyWin20.RealEntryPoint();
    ↓
if __name__ == "__main__":
    IpyWin20.RealEntryPoint();

3.ソース先頭の import 宣言を、以下の例のようにいじる。

import clr
import System
clr.AddReferenceByPartialName("System.Windows.Forms")
clr.AddReferenceByPartialName("System.Drawing")
clr.AddReferenceByPartialName("IronPython")

from System.Windows.Forms import *
#from System.ComponentModel import *
from System.Drawing import *
from clr import *
class IpyWin2: # namespace
...


以上で、Visual Studio 2005 for IronPython上で作ったソースが、ipy.exe単体で動くようになります。


という訳で、以下に先ほどのソースを丸ごと載せます。
(IronPython 1.0.1で動作確認しています)

import clr
import System
clr.AddReferenceByPartialName("System.Windows.Forms")
clr.AddReferenceByPartialName("System.Drawing")
clr.AddReferenceByPartialName("IronPython")

from System.Windows.Forms import *
#from System.ComponentModel import *
from System.Drawing import *
from clr import *
class IpyWin2: # namespace
    
    class Form1(System.Windows.Forms.Form):
        """type(_panel1) == System.Windows.Forms.Panel, type(_splitContainer1) == System.Windows.Forms.SplitContainer, type(_lblURL) == System.Windows.Forms.Label, type(_btnGO) == System.Windows.Forms.Button, type(_txtURL) == System.Windows.Forms.TextBox, type(_Web) == System.Windows.Forms.WebBrowser, type(_txtMSG) == System.Windows.Forms.TextBox"""
        __slots__ = ['_panel1', '_splitContainer1', '_lblURL', '_btnGO', '_txtURL', '_Web', '_txtMSG']
        def __init__(self):
            self.InitializeComponent()
        
        @accepts(Self(), bool)
        @returns(None)
        def Dispose(self, disposing):
            
            
            
            super(type(self), self).Dispose(disposing)
        
        @returns(None)
        def InitializeComponent(self):
            self._panel1 = System.Windows.Forms.Panel()
            self._lblURL = System.Windows.Forms.Label()
            self._btnGO = System.Windows.Forms.Button()
            self._txtURL = System.Windows.Forms.TextBox()
            self._splitContainer1 = System.Windows.Forms.SplitContainer()
            self._Web = System.Windows.Forms.WebBrowser()
            self._txtMSG = System.Windows.Forms.TextBox()
            self._panel1.SuspendLayout()
            self._splitContainer1.Panel1.SuspendLayout()
            self._splitContainer1.Panel2.SuspendLayout()
            self._splitContainer1.SuspendLayout()
            self.SuspendLayout()
            # 
            # panel1
            # 
            self._panel1.Controls.Add(self._lblURL)
            self._panel1.Controls.Add(self._btnGO)
            self._panel1.Controls.Add(self._txtURL)
            self._panel1.Dock = System.Windows.Forms.DockStyle.Top
            self._panel1.Location = System.Drawing.Point(0, 0)
            self._panel1.Name = 'panel1'
            self._panel1.Size = System.Drawing.Size(292, 25)
            self._panel1.TabIndex = 0
            # 
            # lblURL
            # 
            self._lblURL.AutoSize = True
            self._lblURL.Location = System.Drawing.Point(3, 3)
            self._lblURL.Name = 'lblURL'
            self._lblURL.Size = System.Drawing.Size(45, 12)
            self._lblURL.TabIndex = 1
            self._lblURL.Text = 'URL(&U):'
            # 
            # btnGO
            # 
            self._btnGO.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right
            self._btnGO.Location = System.Drawing.Point(234, 2)
            self._btnGO.Name = 'btnGO'
            self._btnGO.Size = System.Drawing.Size(55, 20)
            self._btnGO.TabIndex = 1
            self._btnGO.Text = 'GO!'
            self._btnGO.UseVisualStyleBackColor = True
            self._btnGO.Click += self._btnGO_Click
            # 
            # txtURL
            # 
            self._txtURL.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
            self._txtURL.Location = System.Drawing.Point(54, 3)
            self._txtURL.Name = 'txtURL'
            self._txtURL.Size = System.Drawing.Size(174, 19)
            self._txtURL.TabIndex = 0
            # 
            # splitContainer1
            # 
            self._splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
            self._splitContainer1.Location = System.Drawing.Point(0, 25)
            self._splitContainer1.Name = 'splitContainer1'
            self._splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal
            # 
            # splitContainer1.Panel1
            # 
            self._splitContainer1.Panel1.Controls.Add(self._Web)
            # 
            # splitContainer1.Panel2
            # 
            self._splitContainer1.Panel2.Controls.Add(self._txtMSG)
            self._splitContainer1.Size = System.Drawing.Size(292, 301)
            self._splitContainer1.SplitterDistance = 178
            self._splitContainer1.TabIndex = 1
            # 
            # Web
            # 
            self._Web.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
            self._Web.Location = System.Drawing.Point(0, 0)
            self._Web.MinimumSize = System.Drawing.Size(20, 20)
            self._Web.Name = 'Web'
            self._Web.Size = System.Drawing.Size(292, 175)
            self._Web.TabIndex = 0
            self._Web.DocumentCompleted += self._Web_DocumentCompleted_1
            # 
            # txtMSG
            # 
            self._txtMSG.Dock = System.Windows.Forms.DockStyle.Fill
            self._txtMSG.Location = System.Drawing.Point(0, 0)
            self._txtMSG.Multiline = True
            self._txtMSG.Name = 'txtMSG'
            self._txtMSG.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            self._txtMSG.Size = System.Drawing.Size(292, 119)
            self._txtMSG.TabIndex = 0
            # 
            # Form1
            # 
            self.ClientSize = System.Drawing.Size(292, 326)
            self.Controls.Add(self._splitContainer1)
            self.Controls.Add(self._panel1)
            self.Name = 'Form1'
            self.Text = 'Form1'
            self._panel1.ResumeLayout(False)
            self._panel1.PerformLayout()
            self._splitContainer1.Panel1.ResumeLayout(False)
            self._splitContainer1.Panel2.ResumeLayout(False)
            self._splitContainer1.Panel2.PerformLayout()
            self._splitContainer1.ResumeLayout(False)
            self.ResumeLayout(False)
        
        @accepts(Self(), System.Object, System.EventArgs)
        @returns(None)
        def _btnGO_Click(self, sender, e):
            self._Web.Navigate(self._txtURL.Text)
        
        @accepts(Self(), System.Object, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
        @returns(None)
        def _Web_DocumentCompleted_1(self, sender, e):
            s = "DocumentComplete: %s\n" % (e.Url)
            self._txtMSG.Text += s
        
    

class IpyWin20: # namespace
    from System import *
    from System.Windows.Forms import *
    from Form1 import *
    
    @staticmethod
    def RealEntryPoint():
        Application.EnableVisualStyles()
        Application.Run(IpyWin2.Form1())

#if __name__ == "Program":
if __name__ == "__main__":
    IpyWin20.RealEntryPoint();

ちなみに、Visual Studio 2005 for IronPython上で、自分が手を加えた箇所は、 _btnGO_Click メソッドと _Web_DocumentCompleted_1 メソッドの内部処理だけです。
後は、全て Visual Studioが良きに計らってくれます。

いやぁ、便利便利。