I have some UI application that lives in the user's task bar that is written in C#. The EXE for the tool is checked in to our source control system on a number of projects that use it so we are able to update the version they run with by checking in updated EXE.
The problem is that when the users get the latest revision of the exe, the program is often running, and the sync fails on their machine. I want to fix it so the program doesn't lock the exe and any dependent DLL's when it runs so they can sync without having to shut down the program.
Currently, I have a program that takes an executable as a parameter and will launch it from memory by reading the assembly contents into memory ahead of time. Unfortunetly, this totally fails when it comes to the DLL's that the program requires.
The code I have right now looks something like this:
public class ExecuteFromMemory
{
public static void Main(string[] args)
{
//Figure out the name of the EXE to launch and the arguments to forward to it
string fileName = args[0];
string[] realArgs = new string[args.Length - 1];
Array.Copy(args, 1, realArgs, 0, args.Length - 1);
//Read the assembly from the disk
byte[] binary = File.ReadAllBytes(fileName);
//Execute the loaded assembly using reflection
Assembly memoryAssembly = null;
try
{
memoryAssembly = Assembly.Load(binary);
}
catch (Exception ex)
{
//Print error message and exit
}
MethodInfo method = memoryAssembly.EntryPoint;
if (method != null && method.IsStatic)
{
try
{
method.Invoke(null, new object[] { realArgs });
}
catch(Exception ex)
{
//Print error message and exit
}
}
else
{
//Print error message and exit
}
}
}
My question is, am I doing something totally stupid? Is there a better way to handle this? If not, what should I do to support handling external dependencies?
For example, the above code fails to load any dependent files if you try to run 'Foo.exe' that uses functions from 'Bar.dll', the 'Foo.exe' will be overwriteable, but 'Bar.dll' is still locked and can't be overwritten.
I tried getting the list of referenced assemblies from the 'GetReferencedAssemblies()' method on the loaded assmebly, but that doesn't seem to give any indication where the assemblies should be loaded from... Do I need to search for them myself? If so, what's the best way to do this?
It seems like other people might have come across this before, and I don't want to re-invent the wheel.
- Update: The EXE is checked in because thats how we distribute our in-house tools to the teams that use them. Its not optimal for this use-case, but I don't have the opportunity to change that policy.