web-dev-qa-db-fra.com

Incorporation d'un exécutable externe dans un programme C #

Comment incorporer un exécutable externe dans mon application C # Windows Forms?

Edit: Je dois l’intégrer car c’est une application console libre externe (créée en C++) à partir de laquelle je lis les valeurs de sortie à utiliser dans mon programme. Ce serait bien et plus professionnel de l'avoir intégré.

La deuxième raison est la nécessité d'intégrer un fichier de projecteur Flash dans une application .NET.

33
Josh

Voici un exemple de code permettant de parvenir à ce résultat, sans vérification d'erreur. Assurez-vous également que la licence du programme à intégrer permet ce type d'utilisation.

// extracts [resource] into the the file specified by [path]
void ExtractResource( string resource, string path )
{
    Stream stream = GetType().Assembly.GetManifestResourceStream( resource );
    byte[] bytes = new byte[(int)stream.Length];
    stream.Read( bytes, 0, bytes.Length );
    File.WriteAllBytes( path, bytes );
}

string exePath = "c:\temp\embedded.exe";
ExtractResource( "myProj.embedded.exe", exePath );
// run the exe...
File.Delete( exePath );

La seule difficulté consiste à obtenir la valeur correcte pour le premier argument à ExtractResource. Il devrait avoir la forme "namespace.name", où namespace est l'espace de nommage par défaut de votre projet (à rechercher sous Projet | Propriétés | Application | Espace de noms par défaut). La deuxième partie est le nom du fichier, que vous devrez inclure dans votre projet (assurez-vous de définir l'option de génération sur "Ressources incorporées"). Si vous placez le fichier dans un répertoire, par exemple Ressources, ce nom devient alors une partie du nom de la ressource (par exemple, "myProj.Resources.Embedded.exe"). Si vous rencontrez des problèmes, essayez d’ouvrir votre binaire compilé dans Reflector et consultez le dossier Ressources. Les noms énumérés ici sont les noms que vous souhaitez transmettre à GetManifestResourceStream.

20
Charlie

Manière la plus simple, à partir de ce que dit Will :

  1. Ajouter le fichier .exe à l'aide de Resources.resx
  2. Code ceci:

    string path = Path.Combine(Path.GetTempPath(), "tempfile.exe");  
    File.WriteAllBytes(path, MyNamespace.Properties.Resources.MyExecutable);
    Process.Start(path);
    
54
dav_i

Ajoutez-le simplement à votre projet et définissez l'option de génération sur "Ressources incorporées".

14
scottm

C'est probablement le plus simple:

byte[] exeBytes = Properties.Resources.myApp;
string exeToRun = Path.Combine(Path.GetTempPath(), "myApp.exe");

using (FileStream exeFile = new FileStream(exeToRun, FileMode.CreateNew))
    exeFile.Write(exeBytes, 0, exeBytes.Length);

Process.Start(exeToRun);
7
nawfal

L'exécutable est-il un assemblage géré? Si c'est le cas, vous pouvez utiliser ILMerge pour fusionner cette assemblée avec la vôtre.

4
Andrew Hare
  1. Ajouter un fichier au projet VS
  2. Marquer comme "ressource incorporée" -> Propriétés du fichier
  3. Utilisez name pour résoudre: [Nom de l'assembly]. [Nom de la ressource incorporée] comme "MyFunkyNTServcice.SelfDelete.bat"

Votre code a un bug de ressource (le descripteur de fichier n'est pas libéré!), Corrigez-le en:

public static void extractResource(String embeddedFileName, String destinationPath)
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        var arrResources = currentAssembly.GetManifestResourceNames();
        foreach (var resourceName in arrResources)
        {
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
                {
                    using (var output = File.OpenWrite(destinationPath))
                        resourceToSave.CopyTo(output);
                    resourceToSave.Close();
                }
            }
        }
    }
1
Martin.Martinsson

Voici ma version: Ajoutez le fichier au projet en tant qu'élément existant, changez les propriétés du fichier en "ressource incorporée"

Pour extraire dynamiquement le fichier à un emplacement donné: (cet exemple ne teste pas l'emplacement pour les autorisations d'écriture, etc.)

    /// <summary>
    /// Extract Embedded resource files to a given path
    /// </summary>
    /// <param name="embeddedFileName">Name of the embedded resource file</param>
    /// <param name="destinationPath">Path and file to export resource to</param>
    public static void extractResource(String embeddedFileName, String destinationPath)
    {
        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        string[] arrResources = currentAssembly.GetManifestResourceNames();
        foreach (string resourceName in arrResources)
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                Stream resourceToSave = currentAssembly.GetManifestResourceStream(resourceName);
                var output = File.OpenWrite(destinationPath);
                resourceToSave.CopyTo(output);
                resourceToSave.Close();
            }
    }
1
Fred B

Extraire quelque chose sous forme de chaîne, si nécessaire:

public static string ExtractResourceAsString(String embeddedFileName)
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        var arrResources = currentAssembly.GetManifestResourceNames();
        foreach (var resourceName in arrResources)
        {
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
                {
                    using (var output = new MemoryStream())
                    {
                        resourceToSave.CopyTo(output);
                        return Encoding.ASCII.GetString(output.ToArray());
                    }
                }
            }
        }

        return string.Empty;
    }
0
Martin.Martinsson