Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Najłatwiejszy sposób na system pluginów


Gość Pan Szymek

Rekomendowane odpowiedzi

Opublikowano

Pozwalanie na pisanie wtyczek zdecydowania zwiększa popularność programu. Ale jak się do tego zabrać? Jest sposób o wiele poprawniejszy od przedstawionego poniżej, aczkolwiek uważam, że ten jest o wiele prostszy.

 

Na początek stwórzmy jakieś GUI.

 

 

Teraz napiszmy sobie funkcję do kompilowania w locie kodu z pliku

private CompilerResults skompiluj(string sciezka)
        {
            CompilerParameters parametry = new CompilerParameters();

            parametry.GenerateInMemory = true;
            parametry.TreatWarningsAsErrors = false;
            parametry.GenerateExecutable = false;
            parametry.CompilerOptions = "/optimize";
            parametry.ReferencedAssemblies.AddRange(new string[] { "System.dll", "System.Windows.Forms.dll", System.Reflection.Assembly.GetExecutingAssembly().Location });

            CSharpCodeProvider provider = new CSharpCodeProvider();
            string kod = string.Empty;
            using (StreamReader sr = new StreamReader(sciezka))
                kod = sr.ReadToEnd();
            return provider.CompileAssemblyFromSource(parametry, kod);
        }

Dodajmy funkcję do pokazywania MessageBoxa z błędem

private void _pokazBlad(string wiadomosc)
        {
            MessageBox.Show(wiadomosc, "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

Pozostało dodać kod kliknięcia dla przycisku ładującego

private void button1_Click(object sender, EventArgs e)
        {
            if (!File.Exists(textBox1.Text))
            {
                _pokazBlad("Podany plik nie istnieje!");
                return;
            }

            CompilerResults plugin;
            try
            {
                plugin = skompiluj(textBox1.Text);
            }
            catch (Exception ex)
            {
                _pokazBlad("Wystąpił błąd: " + ex.Message);
                return;
            }

            if (plugin.Errors.HasErrors)
            {
                string bledy = string.Empty;
                foreach (var blad in plugin.Errors)
                    bledy += blad.ToString() + "\n";
                _pokazBlad(string.Format("Plugin zawiera następujące błędy:\n{0}", bledy));
                return;
            }
            var typ = plugin.CompiledAssembly.GetType("Plugin.Plugin", true, true);
            Activator.CreateInstance(typ, this);
        }

No i to tyle, w ten sposób kompilujemy plik podany przez użytkownika, który powinien zawierać namespace Plugin oraz klasę plugin z konstruktorem przyjmującym jako parametr obiekt klasy Form, przykład takiego pluginu

using System;
using System.Windows.Forms;

namespace Plugin
{
    public class Plugin 
    {
		public Plugin(Form parent)
		{			
            var btn = new Button() { Text = "Kliknij!", Dock = DockStyle.Left };
            btn.Click += delegate(object s, EventArgs args)
                {
                    MessageBox.Show("działa!");
                };
            parent.Controls.Add(btn);
		}
	}	
}

 

 

  • 1 rok później...
Opublikowano

sorry za odkop

,ale coś nie działa

(Robię w consoli)

http://screenshot.sh/m3cLyKZ2gBYJT

 

Coś po zmieniałem w kodzie .txt

i teraz

http://screenshot.sh/oeWr7MTKgqTgV

http://screenshot.sh/n9CjYsnLf3JDT

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            var kod = Encoding.UTF8.GetString(Convert.FromBase64String("dXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLldpbmRvd3MuRm9ybXM7DQoNCm5hbWVzcGFjZSBQbHVnaW4NCnsNCiAgICBwdWJsaWMgY2xhc3MgUGx1Z2luIA0KICAgIHsNCgkJcHVibGljIFBsdWdpbihGb3JtIHBhcmVudCkNCgkJewkJCQ0KICAgICAgICAgICAgdmFyIGJ0biA9IG5ldyBCdXR0b24oKSB7IFRleHQgPSAiS2xpa25paiEiLCBEb2NrID0gRG9ja1N0eWxlLkxlZnQgfTsNCiAgICAgICAgICAgIGJ0bi5DbGljayArPSBkZWxlZ2F0ZShvYmplY3QgcywgRXZlbnRBcmdzIGFyZ3MpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94LlNob3coImR6aWHFgmEhIik7DQogICAgICAgICAgICAgICAgfTsNCiAgICAgICAgICAgIHBhcmVudC5Db250cm9scy5BZGQoYnRuKTsNCgkJfQ0KCX0JDQp9"));
            CompilerParameters parametry = new CompilerParameters()
            {
                GenerateInMemory = true,
                TreatWarningsAsErrors = false,
                GenerateExecutable = false,
                CompilerOptions = "/optimize"
            };
            parametry.ReferencedAssemblies.AddRange(new string[] { "System.dll", "System.Windows.Forms.dll", System.Reflection.Assembly.GetExecutingAssembly().Location });
            var res = new CSharpCodeProvider().CompileAssemblyFromSource(parametry, kod);
            if (res.Errors.HasErrors)
            {
                var bledy = "";
                foreach (var blad in res.Errors)
                    bledy += blad + "\n";
                MessageBox.Show(bledy);
            }
            else            
                Activator.CreateInstance(res.CompiledAssembly.GetType("Plugin.Plugin", true, true), this);            
        }
    }
}
przed chwilą sprawdziłem, działa, jeśli target to .NET 4.0.
  •  carbonx zmienił(a) tytuł na Najłatwiejszy sposób na system pluginów

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...