2009-04-28 3 views
27

Как встроить внешний исполняемый файл в мое приложение C# Windows Forms?Внедрение внешнего исполняемого файла внутри программы C#

Редактировать: Мне нужно встроить его, потому что это внешнее бесплатное консольное приложение (сделанное на C++), из которого я читаю выходные значения для использования в моей программе. Было бы здорово и профессиональнее, чтобы он был встроен.

Вторая причина - вставить файл Flash-проектора в приложение .NET.

+2

вопрос: что вы хотите с этим "внешним исполняемым"? если просто внедрить и получить его, когда «Embedded Resource» – tofi9

+0

И если он просто «запускает его и получает его выход», то разворачивайте его рядом. Нет необходимости в его встраивании. Кроме того, файл Flash, ваш _could_ просто развернуть его с вашей программой, если это все, что вам действительно нужно. Я подозреваю, что у вас есть еще несколько ** потребностей **, которые вы не удосужились перечислить. :) –

ответ

18

Ниже приведен пример кода, который будет примерно выполнить это минус проверка ошибок любого рода. Кроме того, убедитесь, что лицензия на встроенную программу позволяет использовать этот вид.

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

Единственная сложная часть получает правильное значение первого аргумента ExtractResource. Он должен иметь форму «namespace.name», где пространство имен является пространством имен по умолчанию для вашего проекта (найти это в Project | Properties | Application | Default namespace). Вторая часть - это имя файла, который вам нужно будет включить в свой проект (обязательно установите для опции сборки значение «Встроенный ресурс»). Если вы поместите файл в каталог, например. Ресурсы, то это имя становится частью имени ресурса (например, «myProj.Resources.Embedded.exe»). Если у вас возникли проблемы, попробуйте открыть скомпилированный двоичный файл в Reflector и посмотреть в папке «Ресурсы». Названия, перечисленные здесь, - это имена, которые вы перешли бы на GetManifestResourceStream.

+2

Ahem. GMRS - это OLD-способ сделать это. Вы можете просто вставлять .exe в сборку как массив байтов, доступный как свойство. Два шага, чтобы получить его и сохранить на диск, а не монстра с магическими строками, которые вы предложили. [Вот страница о том, как создавать строго типизированные ресурсы в VS.] (http://msdn.microsoft.com/en-us/library/t69a74ty (VS.90) .aspx) – Will

+23

К сожалению, это не самый современный ответ, но я не уверен, что он действительно заслуживает того, чтобы его называли «чудовищем». – Charlie

4

Является ли исполняемый файл управляемой сборкой? Если это так, вы можете использовать ILMerge, чтобы объединить эту сборку с вашей.

+1

Как бы он запустил его? – beppe9000

12

Просто добавьте его в свой проект и установить опцию сборки для «Embedded Resource»

5

Это, вероятно, самый простой:

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

Что такое myApp после Properties.Resources? Является ли это классом custmo для встроенного ресурса? – datelligence

+0

@datelligence myApp - это ваше собственное имя ресурса. Тот, который вы добавили/ввели в файл ресурсов. В моем случае это исполняемый файл с расширением .exe. – nawfal

44

Простейшее путь, ведущий на какой из Will said:

  1. Добавьте EXE-файл, используя Resources.resx
  2. код это:

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

Разумеется, целесообразно проверить, существует ли файл и/или удалить файл после этого. –

+1

Это может быть полезно, Что такое MyExecutable после Properties.Resources. [MyExecutable], является ли это определенным объектом для внедренного ресурса? – datelligence

1

Вот моя версия: Добавить файл в проект в качестве существующего элемента, изменения свойств на файл в «внедренный ресурс»

Чтобы динамически извлечь файл в заданном месте: (этот пример не испытывает место для разрешения записи и т.д.)

/// <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
  1. Добавить файл в VS Project
  2. Марка как "Внедренный ресурс" -> свойства файла
  3. Используйте имя для решения: [имя Ассамблеи] [название. встроенный ресурс], как «MyFunkyNTServcice.SelfDelete.bat»

Ваш код имеет ошибку ресурса (дескриптор файла не освобожден!), Пожалуйста, поправьте к:

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(); 
       } 
      } 
     } 
    } 
0

Extract что-то в качестве строки, если это необходимо:

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; 
    } 
Смежные вопросы