ファイル内のコードを実行する

タグの編集
投稿者 xvmm  (中学生) 投稿日時 2011/3/27 13:58:54
中2です。
VB.NETで、ファイル内のコード(たとえば、VBCode.vbc(vbcは独自の拡張子です。))を実行することは可能でしょうか。
例えば、VBCode.vbcの内容は「MsgBox("VBCode.vbc")」で、フォーム上のボタン(Button1)をクリックすると、実行される風にしたいのですが、やり方があれば教えてください。
お願いします。
投稿者 るきお  (社会人) 投稿日時 2011/3/27 16:08:42
>ファイル内のコード(たとえば、VBCode.vbc(vbcは独自の拡張子です。))を実行することは可能でしょうか。
可能です。
VBでは、プログラムから命令してコンパイルを行うことができますし、コンパイルされたものを実行することもできますので組み合わせればファイル内に保存されているソースコードを実行することが可能になります。
ただし、コンパイルやプロジェクトの構成に関する基本的な知識が必要になります。

とりあえずサンプルを作成しましたので参考にしてください。
例1ではおっしゃるようにC:\VBCode.vbcに記述されたソースコードを実行します。
このファイルはutf-8で保存してください。
例2、例3ではプログラムの中で文字列として定義したプログラムを実行します。

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click

        '例1 
        Dim source As String = IO.File.ReadAllText("C:\vb\VBCode.vbc")
        EVal(source)

    End Sub

    Private Sub Button2_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button2.Click

        '例2 
        EVal("MsgBox(""Hello, Visual Basic!"")")

    End Sub

    Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click

        '例3 
        Dim vb As New System.Text.StringBuilder
        vb.AppendLine("Dim x As Integer")
        vb.AppendLine("x = 5 ^ 5 mod 3")
        vb.AppendLine("MsgBox(x)")
        EVal(vb.ToString)
    End Sub

    ''' <summary> 
    ''' 部分的なVisual Basicのソースコードをコンパイルし実行します。 
    ''' sourceではプロシージャやクラスを作成する内容を記述することはできません。 
    ''' 完全なVisual Basicのソースコードをコンパイルし、実行する場合はEvalVBSourceを使用してください。 
    ''' </summary> 
    Public Sub EVal(ByVal source As String)

        'コンパイル実行 
        Dim template As New System.Text.StringBuilder
        template.AppendLine("Public Class Start")
        template.AppendLine("Shared Sub Main()")
        template.AppendLine(source)
        template.AppendLine("End Sub")
        template.AppendLine("End Class")

        EValVBSource(template.ToString)

    End Sub

    ''' <summary> 
    ''' 完全なVisual Basicのソースコードをコンパイルし実行します。 
    ''' 実行はソースコードに含まれる有効なSub Mainから開始するため、ソースコードには必ず有効なSub Mainを含んでください。 
    ''' 単純なコードを実行したいだけの場合はEvalを使用するほうが手軽です。 
    ''' </summary> 
    Public Sub EValVBSource(ByVal fullSource As String)

        'この名前でコンパイルしたファイルを保存する 
        Dim dllFileName As String = "C:\vb\test.exe"

        'コンパイル実行 
        Dim result = CompileString(fullSource, dllFileName)

        'コンパイルエラーがあれば表示する。 
        If result.Errors.Count > 0 Then
            Dim errorMessage As New System.Text.StringBuilder
            For Each er As CodeDom.Compiler.CompilerError In result.Errors
                errorMessage.AppendLine(er.Line & "," & er.ErrorText)
            Next
            Throw New InvalidOperationException(errorMessage.ToString)
        End If

        '実行 
        Process.Start(dllFileName)

    End Sub

    ''' <summary> 
    ''' Visual Basicのソースコードをコンパイルしてdllファイルを作成します。 
    ''' 対象のソースコードはVisual StudioやVisual Basic Expressを使用して作成するソースコードと基本的には同じですが、 
    ''' 前提条件となっている設定がすべて空の状態になっているため、普段は意識していないような設定が必要になります。 
    ''' たとえば、System.Collection名前空間のクラスは名前空間を省略して使用することはできません。 
    ''' ただし、これらの設定をコンパイラに伝えることで通常と同じような記述ができるようにすることはできます。 
    ''' そのような設定がたくさんあるためここでは最低限のものだけを設定しています。 
    ''' </summary> 
    Public Function CompileString(ByVal source As StringByVal resultFile As StringAs CodeDom.Compiler.CompilerResults

        Dim provider As CodeDom.Compiler.CodeDomProvider = CodeDom.Compiler.CodeDomProvider.CreateProvider("VisualBasic")
        Dim referenceAssemblies As String() = {"System.dll"}
        Dim cp As New CodeDom.Compiler.CompilerParameters(referenceAssemblies, resultFile, False)
        cp.CompilerOptions = "/imports:Microsoft.VisualBasic /target:winexe"
        cp.GenerateExecutable = True
        Dim cr As CodeDom.Compiler.CompilerResults = provider.CompileAssemblyFromSource(cp, source)
        Return cr
    End Function

 
End Class
投稿者 xvmm  (中学生) 投稿日時 2011/3/27 21:47:47
説明不足でした。すみません。
コンパイルせずに、実行させることはできるでしょうか。
投稿者 るきお  (社会人) 投稿日時 2011/3/27 23:51:53
>コンパイルせずに、実行させることはできるでしょうか。
できません。

しかし、コンパイルの有無が問題になる理由がわかりません。
私の提案した方法では実現できないのに、コンパイルしないで実行できれば実現できることがありますか?

ディスクに書き込み権限がないとか?
投稿者 shu  (社会人) 投稿日時 2011/3/28 07:43:29
VB Scriptで書くのはどう?