Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как внести изменен. в прилож. с помощью "макроса"? 
V
    Опции темы
htzg
Дата 25.2.2015, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



Доброго времени суток!
Хочу встроить в свое приложение возможность компилировать код на C# и VB "на лету".
Как это сделать я понял:
Код

using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;

Не понятно следующее: в моем приложении будет один экземпляр класса Project, который будет иметь имя project.
Все изменения в приложении будут осуществляться через методы project.
Как сделать так что бы пользователь написав код в блокноте и запустив его генерацию через мое приложение, внес изменения в этот самый экземпляр Project project? Например воспользовался методом Clear() или т.п.
Как внести изменения в project с помощью "макроса" на CS или VB?
Спасибо!
PM MAIL   Вверх
diadiavova
Дата 25.2.2015, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Код, который напишет пользователь, надо будет компилировать в сборку. К примеру код макроса будет оформлен в отдельный класс, в этом классе создай поле project, которое надо будет инициировать из конструктора, сам конструктор получит ссылку через параметр. Вот к этому полю пусть пользователь и обращается. Когда пользовательский код будет скомпилирован, то уже из своего проекта создавай экземпляр класса с пользовательским кодом и попутно передавай ссылку на экземпляр проекта конструктору класса.



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
htzg
Дата 26.2.2015, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



Интерпретировал:

Код

using System;
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;

using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;

using System.Globalization;



namespace IFeelYou
{

    
    public class Project
    {
        public void Touch()
        {
            MessageBox.Show("I Feel You!");
        }
    }



    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        Project project = new Project();
        private void button1_Click(object sender, EventArgs e)
        {
            string code = "using System; " +
                          "namespace IFeelYou" +
                          "{ " +
                          "   public class MyClass " +
                          "   { " +
                          "        public MyClass(Project p) { project = p; }" +
                          "        public Project project {set;get;}" +
                          "        public void Func()" +
                          "        { " +
                                   textBox.Text +
                          "        } " +
                          "   } "+
                          "} ";

            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            CompilerParameters compParameters = new CompilerParameters();
            compParameters.ReferencedAssemblies.Add("System.dll");

            CompilerResults res = codeProvider.CompileAssemblyFromSource(compParameters, code);

            if (res.Errors.HasErrors)
            {
                string lcErrorMsg = "";

                lcErrorMsg = res.Errors.Count.ToString() + " Errors:";
                for (int x = 0; x < res.Errors.Count; x++)
                    lcErrorMsg = lcErrorMsg + "\r\nLine: " +
                                 res.Errors[x].Line.ToString() + " - " +
                                 res.Errors[x].ErrorText;

                MessageBox.Show(lcErrorMsg + "\r\n\r\n" + code,
                                "Compiler Demo");
                return;
            }

            object myClass = res.CompiledAssembly.CreateInstance("MyClass");

            myClass.GetType().GetMethod("MyClass").Invoke(myClass, new object[] { project });
            myClass.GetType().GetMethod("Func").Invoke(myClass, new object[] {});
        }




    }



}



Однако при выполнении выходит сообщение:
user posted image
user posted image

Как подключить Project namespace ?

PM MAIL   Вверх
diadiavova
Дата 26.2.2015, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



htzg, прожектнаймспэйс подключается так же, как ты это сделал с систем. Сначала при компиляции добавь референс на сборку с классом проекта, а в коде используй соответствующий юзинг.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
htzg
Дата 26.2.2015, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



Исправил.
Создал dll и подключил:
Код

using System;
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;

using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;

using System.Globalization;

using IFeelLibrary;             //////////////////////////<<<<<<<<<<<<<<<<<<<<<<<<<<< добавил




namespace IFeelYou
{



    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        Project project = new Project();
        private void button1_Click(object sender, EventArgs e)
        {
            string code = "using System; " +
                          "using IFeelLibrary; " +              //////////////////////////<<<<<<<<<<<<<<<<<<<<<<<<<<< добавил
                          "namespace IFeelYou" +
                          "{ " +
                          "   public class MyClass " +
                          "   { " +
                          "        public MyClass(Project p) { project = p; }" +
                          "        public Project project {set;get;}" +
                          "        public void Func()" +
                          "        { " +
                                        textBox.Text +
                          "        } " +
                          "   } "+
                          "} ";

            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            CompilerParameters compParameters = new CompilerParameters();
            compParameters.ReferencedAssemblies.Add("System.dll");
            compParameters.ReferencedAssemblies.Add("IFeelLibrary.dll");             //////////////////////////<<<<<<<<<<<<<<<<<<<<<<<<<<< добавил

            CompilerResults res = codeProvider.CompileAssemblyFromSource(compParameters, code);

            if (res.Errors.HasErrors)
            {
                string lcErrorMsg = "";

                lcErrorMsg = res.Errors.Count.ToString() + " Errors:";
                for (int x = 0; x < res.Errors.Count; x++)
                    lcErrorMsg = lcErrorMsg + "\r\nLine: " +
                                 res.Errors[x].Line.ToString() + " - " +
                                 res.Errors[x].ErrorText;

                MessageBox.Show(lcErrorMsg + "\r\n\r\n" + code,
                                "Compiler Demo");
                return;
            }

            object myClass = res.CompiledAssembly.CreateInstance("MyClass");

            myClass.GetType().GetMethod("MyClass").Invoke(myClass, new object[] { project });  //<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ошибка!!!
            myClass.GetType().GetMethod("Func").Invoke(myClass, new object[] {});
        }




    }



}




Что то не нравится аргумент:
user posted image
PM MAIL   Вверх
diadiavova
Дата 26.2.2015, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



htzg, Экземпляр ты создаешь предыдущей строкой кода
Код

           object myClass = res.CompiledAssembly.CreateInstance("MyClass");
После чего пытаешься у этого же экземпляра вызвать конструктор. Это в любом случае ни к чему хорошему не приведет. Но в твоем случае экземпляр создан не был, для его создания надо использовать ту перегузку CreateInstance, которой можно передавать аргументы. Она к сожаления довольно длинная и требует много аргументов, это связано с тем, что при вызове параметризированного конструктора требуется предоствить данные, необходимые для того, чтобы можно было нужный конструктор определить безошибочно. Тут либо разберись с этой перегрузкой, либо можно упростить задачу и создавать экземпляр класса с пустым конструктором, а экземпляр проекта либо присваивать нужному свойству уже после создания экземпляра, либо сделать прожект аргумнетом функции и передавать его экземпляр непосредственно при вызове.

Добавлено через 33 секунды
И кстати, криэйтинстэнс тербует полного имени типа с пространством имен.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
diadiavova
Дата 26.2.2015, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Чтоб уже больше не было вопросов smile 

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  runcript.rar 51,58 Kb


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
htzg
Дата 26.2.2015, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



То что надо!  smile 
Спасибо!  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1048 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.