Reputation: 83
I have a basic WinForm Solution (MS VS2013, .Net framework 4.5) for test some methods included in a Dll, using Reflection. My goal is test the main application that it can run two methods of Dll (without referencing the dll in project), and later, run four methods (2 methods added) without stop the main application and run it again, using reflection.
Reflections works fine (if I stop the main application, replacing the dll file and run the main application again, all works fine), but I can't replace the dll at runtime.
The main application has a Timer control with an interval of 60 seconds. Every 60 seconds, a method is executed that checks if a DLL file is in a folder. If a DLL file exists in that folder, I want to use the new DLL in the main application (running) because the new DLL contains old methods (first DLL) and additional methods that the main application needs. However, I am getting an error that the file is in use.
I have read several posts, questions, answers, MEF documentation, AppDomains related, but I have been unable to concatenate the information to be able to implement a solution.
Actually, I thought a lot before post this question, but I confess that I prefer to spend a moment of shame, knowing that you can give me a hand.
It would be for me a great help if you help me with code and specific instructions.
This is the code:
Main application:
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.IO;
namespace testDLLs
{
public partial class Principal : Form
{
public Principal()
{
InitializeComponent();
}
private void Principal_Load(object sender, EventArgs e)
{
labelVersionDll.Text = metodosApoyo.RunDLLFunction("VersionOperaciones");
string cListaOperaciones = metodosApoyo.RunDLLFunction("ListaOperaciones");
string[] aOperaciones = cListaOperaciones.Split('|');
comboBoxOperaciones.Items.Clear();
foreach (string cOperacion in aOperaciones)
{
comboBoxOperaciones.Items.Add(cOperacion);
}
timerForUpdate.Interval = 60000;
timerForUpdate.Enabled = true;
}
private void buttonRun_Click(object sender, EventArgs e)
{
int iOperador1, iOperador2;
string resultadoDesdeDll = null;
string cOperacionSeleccionada;
Int32.TryParse(textBoxOperador1.Text, out iOperador1);
Int32.TryParse(textBoxOperador2.Text, out iOperador2);
cOperacionSeleccionada = comboBoxOperaciones.GetItemText(comboBoxOperaciones.SelectedItem);
object[] parametersArray = new object[] { iOperador1, iOperador2 };
resultadoDesdeDll = metodosApoyo.RunDLLFunction(cOperacionSeleccionada, parametersArray);
textBoxResultado.Text = resultadoDesdeDll;
}
private void timerForUpdate_Tick(object sender, EventArgs e)
{
labelUpdateStatus.Text = "Checking updates ...";
notifyIconUpdate.Visible = true;
notifyIconUpdate.BalloonTipText = "Instalando nuevo DLL....";
notifyIconUpdate.BalloonTipTitle = "Info:";
notifyIconUpdate.ShowBalloonTip(5000);
if (File.Exists(@"C:\DLLsForCopy\OperacionesDLL.dll"))
{
File.Copy(@"C:\DLLsForCopy\OperacionesDLL.dll", @"D:\DLLs\OperacionesDLL.dll", true);
labelVersionDll.Text = metodosApoyo.RunDLLFunction("VersionOperaciones");
string cListaOperaciones = metodosApoyo.RunDLLFunction("ListaOperaciones");
string[] aOperaciones = cListaOperaciones.Split('|');
comboBoxOperaciones.Items.Clear();
foreach (string cOperacion in aOperaciones)
{
comboBoxOperaciones.Items.Add(cOperacion);
}
}
labelUpdateStatus.Text = "";
notifyIconUpdate.Visible = false;
}
}
}
Class in project, for some functions for Main application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace testDLLs
{
class metodosApoyo
{
public static string RunDLLFunction(string cMetodo, object[] aParametros = null)
{
string cRetornoGlobal = "";
Object resultado = null;
string cOperacionSeleccionada = cMetodo;
Assembly assembly = Assembly.LoadFile(@"D:\DLLs\OperacionesDLL.dll");
Type type = assembly.GetType("OperacionesDLL.Operaciones");
MethodInfo methodInfo = type.GetMethod(cOperacionSeleccionada);
ParameterInfo[] parameters = methodInfo.GetParameters();
object classInstance = Activator.CreateInstance(type, null);
object[] parametersArray = null;
if (aParametros != null)
{
parametersArray = new object[aParametros.Length];
int i = 0;
foreach (object value in aParametros)
{
parametersArray[i] = aParametros[i];
i++;
}
}
resultado = methodInfo.Invoke(methodInfo, parametersArray);
cRetornoGlobal = (string)resultado;
return cRetornoGlobal;
}
}
}
DLL source (OperacionesDLL.dll):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OperacionesDLL
{
public class Operaciones
{
public static string VersionOperaciones()
{
string retorno;
retorno = "1.0701-16";
return retorno;
}
public static string ListaOperaciones()
{
string retorno;
retorno = "Suma|Resta|Multiplicación|División";
return retorno;
}
public static string Suma(int operador1, int operador2)
{
int resultado;
string retorno;
resultado = operador1 + operador2;
retorno = resultado.ToString();
return retorno;
}
public static string Resta(int operador1, int operador2)
{
int resultado;
string retorno;
resultado = operador1 - operador2;
retorno = resultado.ToString();
return retorno;
}
public static string Multiplicación(int operador1, int operador2)
{
int resultado;
string retorno;
resultado = operador1 * operador2;
retorno = resultado.ToString();
return retorno;
}
public static string División(int operador1, int operador2)
{
int resultado;
string retorno;
resultado = operador1 / operador2;
retorno = resultado.ToString();
return retorno;
}
}
}
Thanks in advance.
Upvotes: 1
Views: 3187
Reputation: 8531
You can do what you're describing by using the Managed Addin Framework (MAF) in the System.Addin
namespace. I've used it to write apps that scans a folder for DLLs and dynamically loads them. You can also use it to unload and reload DLLs as they appear and disappear from the folder.
Upvotes: 2