C# Launching another WPF program from a byte array

308 views Asked by At

First of all, let me say that I've looked through this, and i still haven't been able to find a great solution to my problem. (I will elaborate in post)

Now to the point. I have a program which I want to secure with a login. My setup is as follows:

Login.exe

Application.exe (Gathered from server into byte[])

The user should login, and when successfully logged in, get the server file (Application.exe) and run it, however this file must not be stored locally on the users machine. Instead, this file, which is stored as a byte array, should be launched as a program, but, if possible, not with a location on the harddrive.

Here's how the user would see it:

  • First they'd get the login application, login and the application would download the file from server, and execute it.

Now the main problem i've been struggling with is, that whenever i load this byte array, i get the following Exception:

System.Reflection.TargetInvocationException: The destination of an activation triggered an exception. ---> System.InvalidOperationException: Can not create more than one instance of System.Windows.Application in the same AppDomain.

I've tried with multiple ways, but I've always ended up with the following code:

Assembly a = Assembly.Load(tmpbytearray);
MethodInfo method = a.EntryPoint;
if (method != null)
{
    object o = a.CreateInstance(method.Name);
    method.Invoke(o, null);
}

I've also tried with

Assembly assembly = Assembly.Load(tmpsrc);
//entrypoint: MyMainApplication.App.Main
Type type = assembly.GetType("MyMainApplication.App");
var obj = Activator.CreateInstance(type);
type.InvokeMember("Main",
    BindingFlags.Default | BindingFlags.InvokeMethod,
    null,
    obj,
    null);

But still stuck with the same Exception.

As I've read through the reference (Section B and C) from the top I've also seen the usage of CreateInstanceFromAndUnwrap, but as I can't find a way to supply it with a byte array, instead of a file path, I've decided not to go that way. Now I'm back to square one, and therefore asking here in my last hopes to sum up a solution to this project.

If i've made some misunderstandings throughout the post, feel free to ask, as I will do my best to be as clear and understandable as possible.

Thanks in advance!

UPDATE (Maybe another approach) I've now thought of making a small console based application, which would act as a "launcher" for this application. However this also gives an exception:

System.Reflection.TargetInvocationException: The destination of an activation triggered an exception. ---> System.IO.IOException: The resource mainwindow.xaml was not found.

This exception is really weird, as the application itself works when ran. So the following:

Assembly a = Assembly.Load(tmpsrc);
MethodInfo method = a.EntryPoint;
if (method != null)
{
    object o = a.CreateInstance(method.Name);
    method.Invoke(o, null); //Exception.
}

Depending on what might be the most easy solution, what would you prefer, and how would you think of a possible solution to any of the approaches (The second, or first approach)?

1

There are 1 answers

0
Mikk809h On

(I cannot mark this as complete, but this question has now been solved)

So, some struggles later, I've finally managed to get this working.

I ended up trying many things, but the solution for me was based on this question.

I took the loader class in my Login Application and added the rest after the login has been authorized successfully:

var domain = AppDomain.CreateDomain("test");
domain.Load("Login");

var loader = (Loader)domain.CreateInstanceAndUnwrap("Login", "Login.Loader");
loader.Load(tmpsrc);

After that it somehow worked, which i'm quite surprised for. But anyways, thanks for the help and pinpoints into the proper subjects!