Динамическая компиляция приложений с визуальным интерфейсом - C#
Формулировка задачи:
Часто видел разные примеры программной компиляции кода консольных приложений типа вот этого:
А как можно скомпилить программно код проэкта приложения windows forms. Проблема в том что не пойму как соединить весь код приложения(programs.cs, сама форма и дополнительные компоненты)
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.CSharp;
namespace ConsoleCompiler
{
internal class Program
{
private static void Main(string[] args)
{
// Source code для компиляции
string source =
@"
namespace Foo
{
public class Bar
{
static void Main(string[] args)
{
Bar.SayHello();
}
public static void SayHello()
{
System.Console.WriteLine(""Hello World"");
}
}
}
";
// Настройки компиляции
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters compilerParams = new CompilerParameters
{OutputAssembly = "D:\\Foo.EXE", GenerateExecutable = true};
// Компиляция
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);
// Выводим информацию об ошибках
Console.WriteLine("Number of Errors: {0}", results.Errors.Count);
foreach (CompilerError err in results.Errors)
{
Console.WriteLine("ERROR {0}", err.ErrorText);
}
}
}
}
Нашёл способ скомпилить программно, но появилась новая проблема: Как сделать чтобы скомпилиное приложение при запуске запускало только форму не открывая командную строку(у меня вначале открывает командную строку, а потом уже форму, если закрыть форму, закроется и командная строка, если закрыть командную строку закроется и форма!
Вот мой код на компиляцию:
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string source =
@"
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
static class Program
{
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
partial class Form1
{
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name= " + "\"" + "disposing" + "\"" + @" >истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(135, 214);
this.textBox1.Name = " + "\"" + "textBox1" + "\"" + @";
this.textBox1.Size = new System.Drawing.Size(341, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = " + "\"" + "Проверка" + "\"" + @";
this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(682, 471);
this.Controls.Add(this.textBox1);
this.Name = " + "\"" + "Form1" + "\"" + @";
this.Text = " + "\"" + "Form1" +"\"" + @";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
";
// Настройки компиляции
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters compilerParams = new CompilerParameters { OutputAssembly = "D:\\Мои документы\\Form1.EXE", GenerateExecutable = true };
compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.ReferencedAssemblies.Add("System.Core.dll");
compilerParams.ReferencedAssemblies.Add("System.Data.dll");
compilerParams.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
compilerParams.ReferencedAssemblies.Add("System.Deployment.dll");
compilerParams.ReferencedAssemblies.Add("System.Drawing.dll");
compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
compilerParams.ReferencedAssemblies.Add("System.Xml.dll");
compilerParams.ReferencedAssemblies.Add("System.Xml.Linq.dll");
// Компиляция
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);
//Выводим инфу об ошибках
textBox1.Text = "Количество ошибок: " + results.Errors.Count;
int n = 0;
foreach (CompilerError err in results.Errors)
{
n = n + 1;
richTextBox1.Text = richTextBox1.Text + "Ошибка №" + n + err.ErrorText + "\n";
}
}
}
}Решение задачи: «Динамическая компиляция приложений с визуальным интерфейсом»
textual
Листинг программы
CompilerParameters compilerParams = new CompilerParameters {
OutputAssembly = "D:\\Мои документы\\Form1.EXE",
GenerateExecutable = true,
CompilerOptions = "/target:winexe" };