Запуск dll .NET 5 из своего кода

162
10 мая 2022, 06:30

Хочу запустить dll написанную .NET 5 из своего кода тоже на .NET 5.

Если взять консольное приложение то все работает, я его запускаю. Вот код

Assembly asm = Assembly.LoadFrom(@"ConsoleApp2.dll");
Console.WriteLine(asm.FullName);
Type t = asm.GetType("ConsoleApp2.Program", true, true);
object obj = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod("Main", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
object result = method.Invoke(obj, new object[] { new string[] { } });

Берем тот же код и запускаем winform dll, меняем только название dll. winform dll это обычный новый проект без изменений. Я тестирую. Мне нужно будет запускать разные dll при необходимости.

Assembly asm = Assembly.LoadFrom(@"WindowsFormsApp1.dll");
Type t = asm.GetType("WindowsFormsApp1.Program", true, true);
object obj = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod("Main", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
object result = method.Invoke(obj, new object[] { new string[] { } });

Получаем ошибку

Unhandled exception. System.MissingMethodException: Cannot create an abstract class.
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
   at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at ConsoleApp3.Program.Main(String[] args) in D:\VSproject\ConsoleApp3\ConsoleApp3\Program.cs:line 13

Ошибка в этой строчке

object obj = Activator.CreateInstance(t);

На ней вылет.

код WindowsFormsApp1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
    static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Что я не так делаю?

StackTrace

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at ConsoleApp3.Program.Main(String[] args) in D:\VSproject\ConsoleApp3\ConsoleApp3\Program.cs:line 21
Answer 1

В приложении WinForms у вас статический класс - невозможно создать его экземпляр.

Получив тип:

Type t = asm.GetType("...", true, true);

проверьте, абстрактный (статический) он или нет. И далее либо создаёте его экземпляр, либо сразу вызываете нужный метод.

MethodInfo method = t.GetMethod("Main", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
if (t.IsAbstract)
{
    Console.WriteLine("Static");
    object result = method.Invoke(null, new object[] { new string[] { } });
}
else
{
    Console.WriteLine("Instance");
    object obj = Activator.CreateInstance(t);
    object result = method.Invoke(obj, new object[] { new string[] { } });
}
READ ALSO
&quot;включение&quot; и &quot;выключение&quot; эффекта

"включение" и "выключение" эффекта

При нажатии на объект - объект должен "исчезать", а на его месте должен появляться эффект

139
Поиск по сообщениям discord.js

Поиск по сообщениям discord.js

Как я могу осуществить поиск сообщений по отдельному содержанию, в отдельном канале? Возможно ли это вообще? JavaScript

256
открытые сабменю по клику

открытые сабменю по клику

Есть две части меню, по клику на которые должно открываться соответствующее сабменюУ меня открываются оба сабменю

165