C'est tout à fait possible - je l'ai fait moi-même - mais c'est plutôt fiddly et plus de code managé. Il n'y a pas d'API .NET pour cela, ni d'API native pour PInvoke. Vous devrez donc manipuler la charge à la main, ce qui nécessitera une certaine connaissance du format de fichier PE (Portable Executable) utilisé pour les modules tels que DLL et EXE - http://msdn.microsoft.com/en-us/magazine/cc301805.aspx. Il y aura beaucoup de manipulation de pointeur (imposant l'utilisation de blocs {} dangereux) et PInvoke.
Commencez par charger le fichier PE en mémoire (ou utilisez MapViewOfFile). Un fichier PE est composé de différentes sections contenant du code, des données ou des ressources. Les décalages de chaque section dans le fichier ne correspondent pas toujours aux décalages en mémoire prévus, donc quelques ajustements mineurs sont nécessaires.
Chaque fichier PE suppose qu'il sera chargé à une certaine adresse de base dans la mémoire virtuelle. À moins que vous ne puissiez vous en assurer, vous devrez parcourir la table de relocalisation du fichier PE pour ajuster les pointeurs en conséquence.
Chaque fichier PE a également une liste de table d'importation que d'autres fonctions de DLL qu'il veut appeler. Vous devrez parcourir cette table et appeler LoadLibrary()/GetProcAddress() pour remplir chaque importation.
Ensuite, la protection de la mémoire doit être correctement définie pour chaque section. En-tête de chaque section note la protection qu'il veut, il suffit donc d'appeler VirtualProtect() pour chaque section avec les bons drapeaux. Au minimum, vous aurez besoin de VirtualProtect le module chargé avec PAGE_EXECUTE_READWRITE ou il est peu probable que vous puissiez exécuter du code.
Enfin une DLL vous devez appeler son point d'entrée, dont l'adresse se trouve dans l'en-tête de PE; vous pouvez alors appeler librement les fonctions exportées.
Puisque vous voulez exécuter un fichier EXE, vous avez des maux de tête supplémentaires. Vous pouvez simplement créer un nouveau thread et appeler le point d'entrée du fichier EXE, mais de nombreux fichiers EXE peuvent être dérangés car le processus est configuré pour vous, pas le fichier EXE. Il peut également tuer votre processus quand il essaie de sortir. Vous pourriez donc lancer un nouveau processus - peut-être une autre copie de votre EXE principal avec des arguments spéciaux pour lui dire qu'il va exécuter du code différent - auquel cas vous devrez fenager l'EXE dans son espace mémoire. Vous voudrez probablement faire la plupart du travail ci-dessus dans le nouveau processus, pas l'ancien. Vous pouvez soit créer un canal nommé et envoyer les données d'un EXE à l'autre, soit allouer une zone de mémoire partagée nommée avec MapViewOfFile.Bien sûr, le fichier EXE peut encore se fâcher puisque le processus dans lequel il s'exécute n'est pas le sien.
Dans l'ensemble, il est beaucoup plus simple d'écrire dans un fichier temporaire, puis d'utiliser Process.Start().
Si vous voulez toujours le faire à la dure, jetez un oeil à cet exemple en code non managé: http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/. Cela ne couvre pas les exécutables, seulement les DLL, mais si le code ne vous effraie pas, vous devriez bien étendre le processus pour couvrir les exécutables.
http://stackoverflow.com/questions/1224149/how-to-run-unmanaged-executable-from-memory-rather-than-disc –
Pourquoi ne voulez-vous pas créer un fichier temporaire? – Kramii
parce que je préfère exécuter du code propre sans avoir à créer des fichiers temporaires à chaque fois. si je le lance en mémoire, je n'ai pas à penser aux droits d'écriture dans le dossier temporaire. – MichaelD