2016-12-25 1 views
1

Tout d'abord, laissez-moi vous dire que j'ai regardé this, et je n'ai toujours pas trouvé de solution à mon problème. (Je vais élaborer dans la poste)C# Lancement d'un autre programme WPF à partir d'un tableau d'octets

Maintenant au point. J'ai un programme que je veux sécuriser avec un login. Ma configuration est la suivante:

Login.exe

Application.exe (froncé du serveur dans l'octet [])

L'utilisateur doit se connecter, et lorsque vous êtes connecté avec succès, obtenir le fichier du serveur (Application.exe) et l'exécuter, mais ce fichier doit être stocké localement sur la machine de l'utilisateur. Au lieu de cela, ce fichier, qui est stocké sous la forme d'un tableau d'octets, doit être lancé en tant que programme, mais, si possible, pas avec un emplacement sur le disque dur.

Voilà comment l'utilisateur verrait:

  • D'abord, ils obtiendraient l'application de connexion, connectez-vous et l'application serait télécharger le fichier à partir du serveur, et l'exécuter.

Maintenant, le principal problème que j'ai été aux prises avec est, que chaque fois que je charge ce tableau d'octets, je reçois l'exception suivante:

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. 

J'ai essayé avec de multiples façons, mais je ai toujours fini avec le code suivant:

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

J'ai aussi essayé avec

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); 

Mais toujours coincé avec la même exception. Comme je l'ai lu à travers le reference (Section B et C) à partir du haut, j'ai également vu l'utilisation de CreateInstanceFromAndUnwrap, mais comme je ne peux pas trouver un moyen de le fournir avec un tableau d'octets, au lieu de un chemin de fichier, j'ai décidé de ne pas aller de cette façon. Maintenant, je suis de retour à la case départ, et je demande donc ici, dans mes derniers espoirs, de résumer une solution à ce projet.

Si j'ai fait quelques malentendus tout au long de la poste, n'hésitez pas à demander, car je ferai de mon mieux pour être aussi clair et compréhensible que possible.

Merci d'avance!

MISE À JOUR (Peut-être une autre approche) J'ai maintenant pensé à faire une application petite console, qui agirait comme un « lanceur » pour cette application. Cependant, cela donne aussi une exception:

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

Cette exception est vraiment bizarre, car l'application elle-même fonctionne lorsqu'il est lancé.Ainsi, les éléments suivants:

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

Selon ce qui pourrait être la solution la plus facile, que préféreriez-vous, et comment pensez-vous d'une solution possible à l'une des approches (La seconde, ou première approche)?

+0

Cette exception se plaint d'une seconde instance de 'Application'. Vous pouvez essayer de créer un nouveau domaine et de charger l'assembly dans celui-ci. Vous devriez jeter un oeil ici: [Chargement/Déchargement de l'assemblage dans différents AppDomain] (http://stackoverflow.com/questions/2132649/loading-unloading-assembly-in-different-appdomain) –

+0

Une bonne référence en effet, mais peut Je demande comment je serais en mesure d'ajouter le tableau d'octets manuellement, au lieu d'appliquer un chemin de fichier à l'appdomainsetup, parce que cela ne semble pas être une possibilité autant que je sache? – Mikk809h

+0

Créez un assembly intermédiaire qui contient une classe avec une méthode qui accepte le tableau d'octets. Cette méthode doit charger l'assembly à partir du tableau d'octets. Chargez cet assembly intermédiaire dans un nouveau domaine. –

Répondre

0

(je ne peux pas marquer cela comme complète, mais cette question a maintenant été résolu)

Ainsi, quelques luttes plus tard, je l'ai enfin réussi à obtenir ce travail.

J'ai fini par essayer beaucoup de choses, mais la solution pour moi était basée sur this question.

Je pris la classe du chargeur dans mon application Connexion et a ajouté le reste après la connexion a été autorisé avec succès:

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

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

Après cela, il a travaillé en quelque sorte, que je suis très surpris de. Mais de toute façon, merci pour l'aide et les points dans les sujets appropriés!