C# eval内にフォーム

C# eval内でフォームを扱う事が出来ます。ChatGPT 3.5製です。

using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.CSharp; // 必要な名前空間を追加

class Program
{
    static void Main()
    {
        // ファイルパスを取得
        string sourceFile = GenerateSafeSourceCode();

        // コンパイルパラメータの設定
        CompilerParameters parameters = new CompilerParameters();
        parameters.GenerateExecutable = true;
        parameters.OutputAssembly = "b.exe";
        parameters.CompilerOptions = "/target:winexe";

        // .NET Frameworkディレクトリ内のアセンブリを自動的に追加する
        string dotNetFrameworkDirectory = GetDotNetFrameworkDirectory();
        if (dotNetFrameworkDirectory != null)
        {
            string[] frameworkAssemblies = Directory.GetFiles(dotNetFrameworkDirectory, "*.dll");
            foreach (string assemblyPath in frameworkAssemblies)
            {
                // アセンブリが正しい形式のものであるかどうかを確認し、正しくない場合は除外する
                if (IsValidAssembly(assemblyPath))
                {
                    parameters.ReferencedAssemblies.Add(assemblyPath);
                }
            }
        }
        else
        {
            Console.WriteLine(".NET Frameworkディレクトリが見つかりませんでした。");
            return;
        }

        // C#ファイルをコンパイル
        CompilerResults cr = CompileCSharpFile(sourceFile, parameters);

        if (cr.Errors.HasErrors)
        {
            Console.WriteLine("コンパイルエラーが発生しました:");
            foreach (CompilerError error in cr.Errors)
            {
                Console.WriteLine(""+error.FileName+"("+error.Line+","+error.Column+"): "+error.ErrorText);
            }
        }
        else
        {
            Assembly assembly = cr.CompiledAssembly;
            MethodInfo entryPoint = assembly.EntryPoint;
            if (entryPoint != null)
            {
                entryPoint.Invoke(null, null);
            }
            else
            {
                Console.WriteLine("エントリーポイントが見つかりませんでした。");
            }
        }
    }

    static string GenerateSafeSourceCode()
    {
        string sourceCode = @"
            using System;
            using System.Windows.Forms;

            class CSHello
            {
                static void Main()
                {
                    Console.WriteLine(""Hello C# World!"");
                    
                    // ユーザーに確認を求めるダイアログを表示
                    DialogResult result = MessageBox.Show(""Do you want to proceed?"", ""Confirmation"", MessageBoxButtons.OKCancel);
                    
                    // ユーザーがOKを選択した場合のみ、MessageBoxを表示
                    if (result == DialogResult.OK)
                    {
                        MessageBox.Show(""ok"");
                    }
                }
            }";

        // ファイルに書き込み
        using (StreamWriter writer = new StreamWriter("b.cs"))
        {
            writer.Write(sourceCode);
        }

        return "b.cs";
    }

    static CompilerResults CompileCSharpFile(string sourceFile, CompilerParameters parameters)
    {
        using (CSharpCodeProvider provider = new CSharpCodeProvider())
        {
            ICodeCompiler compiler = provider.CreateCompiler();
            return compiler.CompileAssemblyFromFile(parameters, sourceFile);
        }
    }

    static string GetDotNetFrameworkDirectory()
    {
        string dotNetFrameworkDirectory = null;
        try
        {
            dotNetFrameworkDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
        }
        catch (Exception)
        {
            Console.WriteLine("ランタイムディレクトリを取得できませんでした。");
        }
        return dotNetFrameworkDirectory;
    }

    static bool IsValidAssembly(string assemblyPath)
    {
        try
        {
            // Assemblyクラスを使用するため、System.Reflectionを利用
            Assembly.LoadFrom(assemblyPath);
            // ここで、署名済みアセンブリのみを許可するなどの追加の検証を行うことも可能
            return true;
        }
        catch (Exception)
        {
            // 例外が発生した場合は正しい形式のアセンブリではないと見なす
            return false;
        }
    }
}

Leave a Reply