- PR -

動的に作成したプログラムを実行するようなことはできますか?

1
投稿者投稿内容
未記入
常連さん
会議室デビュー日: 2008/03/13
投稿数: 22
投稿日時: 2008-03-21 15:19
初心者です。VB.NETでわからないことがあります。教えてください。

プログラム中でつくった文字列を、プログラムのように動作させることはできますか?

動的にインスタンスを作成して、そのメソッドにアクセスすることはできたのですが、式の評価なども、文字列をそれとして動作させたりできたら、イレギュラーな感じですが、うれしいです。

"If True Then " & VbCrLf & " Msgbox("こんにちは") " & VbCrLf & " End If "

とかっていう文字列をなんか色々いじるとちゃんとプログラムとして動作させるようなことです。無理でしょうか。
未記入
常連さん
会議室デビュー日: 2008/03/13
投稿数: 22
投稿日時: 2008-03-21 15:39
VB.NETから動的にJScriptを動作させる方法がみつかりまして、これで代用できそうな感じです。失礼しました。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2008-03-21 15:45
http://www.atmarkit.co.jp/fdotnet/dotnettips/101compileinvoke/compileinvoke.html
ここらへんも参考になるとおもいます
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2008-03-24 17:31
引用:

"If True Then " & VbCrLf & " Msgbox("こんにちは") " & VbCrLf & " End If "
とかっていう文字列をなんか色々いじるとちゃんとプログラムとして動作させるようなことです。無理でしょうか。



文字列で与えられたVBのプログラムソースコードを実行したい
ということですよね。
私もずっと、すっきりとこれを実現する方法がないものか気になって
いましたので調べてみました。

で、調べ方が悪かったのか、私に理解できるサンプルが見つからなかった
ので結局書いてみました。
でも、あまりわかりやすくてすっきりとしたものにはなりませんでした。
がっかり。

元質問者様のやりたかったことは、別の手段で達成しているとのことで、
すでに遅かったようでさらにがっかりなんですが、もしかしたら将来、
何かの役に立つ方がいらっしゃるかもしれないので、私の作った
がっかりサンプルソースコードを置いときます。

Visual Studio 2008 の.NET Framework3.5ターゲットで動作検証しています。
このままのソースでは.NET Framework1.0,1.1では動作しないと思われます。
これは、.NET Framework 2.0から、ICodeCompiler インターフェイスを経由
せずにCompileAssemblyFromSourceを呼び出すように変更がされたからです。

.NET Framework クラス ライブラリ
ICodeCompiler インターフェイス
http://msdn2.microsoft.com/ja-jp/library/system.codedom.compiler.icodecompiler(VS.80).aspx

もしも使われる方は、私のサンプルを鵜呑みにせず、実際に運用する
プログラムにはコピペせず、以下のMSDNの説明をお読みになって理解
のうえご利用ください。
.NET Framework クラス ライブラリ
System.CodeDom.Compiler 名前空間
http://msdn2.microsoft.com/ja-jp/library/system.codedom.compiler(VS.80).aspx


文字列をコンパイルして実行、という目的をシンプルに表現するために、
意図的にこの順番に平坦に書いています。
実際に使うときは、適宜、メソッド化、クラス化をお勧めします。

コード:
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.Text

Module DynamicCompileAndRun
    Sub main()
        '動的に変更できるVBのプログラムソースコードを文字列化する
        Dim sbSource As New StringBuilder
        sbSource.Append("Imports Microsoft.VisualBasic" + vbCrLf)
        sbSource.Append("Public Class DynamicClass" + vbCrLf)
        sbSource.Append("  Sub DynamicMethod()" + vbCrLf)
        sbSource.Append("    MsgBox(""動的にコンパイルしたプログラムのMsgBox"")" + vbCrLf)
        sbSource.Append("  End Sub" + vbCrLf)
        sbSource.Append("End Class" + vbCrLf)
        Dim sSource = sbSource.ToString()

        'コンパイルを実行する
        Dim oCompilerParameters As New CompilerParameters
        oCompilerParameters.GenerateExecutable = False
        oCompilerParameters.GenerateInMemory = True
        Dim oVBCompiler As New VBCodeProvider
        Dim oCompilerResults As CompilerResults
        oCompilerResults = oVBCompiler.CompileAssemblyFromSource(oCompilerParameters, sSource)

        '動的コンパイルしたソースにエラーがあった場合、エラーを表示して、終了
        If oCompilerResults.Errors.Count >= 1 Then
            Debug.Print("動的に与えられたソースコードにコンパイルエラーがありました。")
            For Each oCompilerError As System.CodeDom.Compiler.CompilerError In oCompilerResults.Errors
                Debug.Print(oCompilerError.ToString())
            Next
            MsgBox("ソースコードにエラーがあります。イミディエイトウィンドウにエラーを表示しました。")
            Exit Sub
        End If

        'コンパイルしたアセンブリをインスタンス化して実行
        Dim oDynamicCompiledAssembly As Assembly = oCompilerResults.CompiledAssembly
        Dim oDynamicCompiledClassType As Type = oDynamicCompiledAssembly.GetType("DynamicClass")
        Dim oDynamicCompiledMethodInfo As MethodInfo = oDynamicCompiledClassType.GetMethod("DynamicMethod")
        Dim oDynamicCompiledInstance As Object = Activator.CreateInstance(oDynamicCompiledClassType)
        oDynamicCompiledMethodInfo.Invoke(oDynamicCompiledInstance, Nothing)
    End Sub
End Module



_________________
たつごろー
codeseek
こみゅぷらす
1

スキルアップ/キャリアアップ(JOB@IT)