using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Reflection;

namespace SystemInfoDemo_Reflection
{
    public partial class Form1 : Form
    {
        //private const string nazwaPlikuDLL = @"c:\Documents and Settings\jacek\Moje dokumenty\Visual Studio 2010\Projects\SystemInfo\SystemInfo\bin\Debug\SystemInfo.dll";
        private const string nazwaPlikuDLL = @"SystemInfo.dll";

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (!System.IO.File.Exists(nazwaPlikuDLL))
                    throw new Exception("Brak pliku biblioteki DLL");
                Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
                MessageBox.Show("Wczytano podzespół:\n" + a.FullName + "\nz pliku " + a.Location);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Wczytanie podzespołu z pliku " + nazwaPlikuDLL + " nie powiodło się (" + exc.Message + ").");
                return;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
            string nazwyTypow = "Nazwy klas:\n";
            Type[] typy = a.GetTypes();
            foreach (Type typ in typy) nazwyTypow += typ.FullName + "\n";
            MessageBox.Show(nazwyTypow);
        }

        private const string nazwaKlasy = "Helion.SystemInfo";

        private void button3_Click(object sender, EventArgs e)
        {
            Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
            Type klasa = a.GetType(nazwaKlasy);
            if (klasa == null) MessageBox.Show("Nie znaleziono klasy " + nazwaKlasy);
            //else MessageBox.Show("Znaleziono klasę " + nazwaKlasy);
            else
            {
                string nazwyMetod = "Sygnatury metod:\n";
                MethodInfo[] metody = klasa.GetMethods();
                foreach (MethodInfo metoda in metody) nazwyMetod += metoda.ToString() + "\n";
                MessageBox.Show("Znaleziono klasę " + nazwaKlasy + "\n\n" + nazwyMetod);
            }
        }

        /*
        private void button4_Click(object sender, EventArgs e)
        {
            string nazwaMetody = "Show";
            Type zwracanaWartoscMetody = typeof(void);

            try
            {
                Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
                Type klasa = a.GetType(nazwaKlasy);
                if (klasa == null)
                    throw new Exception("Nie znaleziono klasy " + nazwaKlasy);
                MethodInfo metoda = klasa.GetMethod(nazwaMetody);
                if (metoda == null)
                    throw new Exception("Nie znaleziono metody " + nazwaMetody);
                if (!metoda.IsStatic)
                    throw new Exception("Poszukiwana metoda powinna być statyczna");
                if (metoda.ReturnType != zwracanaWartoscMetody)
                    throw new Exception("Zły typ zwracanej wartości w " + nazwaMetody);
                if (metoda.GetParameters().Length > 0)
                    throw new Exception("Zła liczba argumentów metody " + nazwaMetody);
                MessageBox.Show("Znalazłem metodę");
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message + ".");
                return;
            }
        }
        */

        private void button4_Click(object sender, EventArgs e)
        {
            string nazwaMetody = "GetSystemInfo";

            try
            {
                Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
                Type klasa = a.GetType(nazwaKlasy);
                if (klasa == null)
                    throw new Exception("Nie znaleziono klasy " + nazwaKlasy);
                MethodInfo metoda = klasa.GetMethod(nazwaMetody);
                if (metoda == null)
                    throw new Exception("Nie znaleziono metody " + nazwaMetody);

                ParameterInfo[] parametry = metoda.GetParameters();
                string listaArgumentow = "\nLista argumentow:\n";
                foreach (ParameterInfo parametr in parametry)
                    listaArgumentow += "\t" + parametr.Position + ". " + parametr.ParameterType + " " + parametr.Name + "\n";

                string zwracanyTyp = "\nZwracany typ: " + metoda.ReturnParameter;

                string statyczna = "\nCzy statyczna: " + ((metoda.IsStatic) ? "tak" : "nie");

                MessageBox.Show("Znalazłem metodę " + metoda.Name + "\n" + listaArgumentow + zwracanyTyp + "\n" + statyczna);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message + ".");
                return;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            string nazwaKlasy = "Helion.SystemInfo";
            string nazwaMetody = "Show";
            Type zwracanaWartoscMetody = typeof(void);

            try
            {
                Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
                Type klasa = a.GetType(nazwaKlasy);
                if (klasa == null)
                    throw new Exception("Nie znaleziono klasy " + nazwaKlasy);
                MethodInfo metoda = klasa.GetMethod(nazwaMetody);
                if (metoda == null)
                    throw new Exception("Nie znaleziono metody " + nazwaMetody);
                if (!metoda.IsStatic)
                    throw new Exception("Poszukiwana metoda powinna być statyczna");
                if (metoda.ReturnType != zwracanaWartoscMetody)
                    throw new Exception("Zły typ zwracanej wartości w " + nazwaMetody);
                if (metoda.GetParameters().Length > 0)
                    throw new Exception("Zła liczba argumentów metody " + nazwaMetody);

                metoda.Invoke(null, null);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message + ".");
                return;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string nazwaKlasy = "Helion.SystemInfo";
            string nazwaMetody = "GetSystemInfoBuilder";
            Type zwracanaWartoscMetody = typeof(System.Int32);

            try
            {
                Assembly a = Assembly.LoadFrom(nazwaPlikuDLL);
                Type klasa = a.GetType(nazwaKlasy);
                if (klasa == null)
                    throw new Exception("Nie znaleziono klasy " + nazwaKlasy);
                MethodInfo metoda = klasa.GetMethod(nazwaMetody);
                if (metoda == null)
                    throw new Exception("Nie znaleziono metody " + nazwaMetody);
                if (metoda.ReturnType != zwracanaWartoscMetody)
                    throw new Exception("Zły typ zwracanej wartości w " + nazwaMetody);
                if (metoda.GetParameters().Length != 2)
                    throw new Exception("Zła liczba argumentów metody " + nazwaMetody);

                object obiektSystemInfo = a.CreateInstance(nazwaKlasy);

                StringBuilder informacje = new StringBuilder();
                object[] parametry = new object[2];
                parametry[0] = informacje;
                parametry[1] = false;

                int zwroconaWartosc = (int)metoda.Invoke(obiektSystemInfo, parametry);
                MessageBox.Show("Zwrócona wartość: " + zwroconaWartosc + " (główna wersja platformy .NET)\n\nPobrany łańcuch z informacjami o systemie:\n" + informacje);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message + ".");
                return;
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                dynamic obiektSystemInfo = Assembly.LoadFrom(nazwaPlikuDLL).CreateInstance(nazwaKlasy);
                string informacje = "";
                obiektSystemInfo.GetSystemInfo(out informacje, true);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message + ".");
            }
        }
    }
}
