
[英]ILRepack of .NET 4.7.2 C# console app built with Visual Studio 2017 requires framework installed on Windows 7
[英].NET reference design for GUI app with built-in interactive terminal console (e.g. SublimeText, Visual Studio)
我正在尝试构建一个具有交互式控制台的GUI应用程序,就像在SublimeText中找到的那样。 我希望这是一个有效的问题,因为它似乎是“软件开发所独有的实用,可回答的问题”。
简而言之,我看到在GUI应用程序中具有用于
但是,我还没有遇到使用这种设计的任何现有开源应用程序。 我希望有人能做得到并且可以分享他/她的设计方法。
虽然我确实有一个在.NET中使用反射和调用的半工作解决方案,但它仅限于函数调用,而我无法探究嵌套的内部变量(例如object.property.property)。
为了使问题更具体,这些是我面临的问题:
谢谢。
所以这是对我有用的代码:
namespace ReflectionsTest
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
//Events excluded
private void ExecuteCommand(string command)
{
string cmd = "";
cmd += @"using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Microsoft.CSharp;
using System.Reflection;
using ReflectionsTest;";
// i included a using statement for every namespace i want to adress direct
cmd += @"namespace ReflectionConsole
{
public class RuntimeExecution
{
public static void Main(MainForm parent, TextBox output, FieldInfo[] privateFields)
{
try {";
//the code in a trycatch because i can send every error to a specific output defined as output parameter
cmd += command;
cmd += "}catch (Exception ex) { if(output != null){" +
"output.Text += ex.Message + \"\\n\\r\";"
+"}else{MessageBox.Show(ex.Message);}}}}}";
try {
ExecuteCSharp(cmd);
}
catch (Exception ex) {
textBox2.Text += ex.Message + "\n\r";
}
}
private void ExecuteCSharp(string code)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
List<AssemblyName> assemblys = (Assembly.GetExecutingAssembly().GetReferencedAssemblies()).ToList<AssemblyName>();
foreach (var item in assemblys) {
parameters.ReferencedAssemblies.Add(item.Name + ".dll");
}
string t = Assembly.GetExecutingAssembly().GetName().Name;
parameters.ReferencedAssemblies.Add(t + ".exe");
//Here you have to reference every assembly the console wants access
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
if (results.Errors.HasErrors) {
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors) {
sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
}
throw new InvalidOperationException(sb.ToString());
}
else {
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("ReflectionConsole.RuntimeExecution");
MethodInfo main = program.GetMethod("Main");
FieldInfo[] fields = this.GetType().GetFields(
BindingFlags.NonPublic |
BindingFlags.Instance);
//if everything is correct start the method with some arguments:
// containing class, output, private fields of the containing class for easier access
main.Invoke(null, new object[]{this, textBox2, fields});
}
}
}
}
一些说明:
您已经通过了包含其他所有内容的程序的最高类,因为与父对象相比,访问成员更容易。
您可以访问的公共对象,如parent.obect1.Text = "textXYZ";
您可以通过名称访问私有对象。 这些对象在privateFields中列出。 对于子类,您有两个选择:调用main.Invoke([...])
时更改第一个和第三个参数, main.Invoke([...])
私有字段。
作为建议,您可以在命令中包含.dll,这已经为您提供了实现此目标的方法。 例如GetValueFromFieldByName(object class, string name, Type resultType)
我希望这就是你所希望的^^
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.